from typing_extensions import Protocol from typing import overload, Any, Callable, Generic, Tuple, TypeVar T = TypeVar("T", contravariant=True) U = TypeVar("U", covariant=True) class HasGetItem(Protocol, Generic[T, U]): def __getitem__(self, item: T) -> U: ... class Foo(HasGetItem[int, str]): ... foo = Foo() foo[41] foo["41"] # E: Invalid index type "str" for "Foo"; expected type "int" foo[42].strip() foo[42] + 1 # E: Unsupported operand types for + ("str" and "int") @overload def itemgetter(item: T) -> Callable[[HasGetItem[T, U]], U]: ... @overload def itemgetter(*items: T) -> Callable[[HasGetItem[T, U]], Tuple[U, ...]]: ...