Interview frequency: …
Short answer
A TypeVar represents an unknown type that must stay the same across parts of a signature, and Generic lets you define a class that preserves the type of what it holds; since Python 3.12 there is also the shorthand syntax def first[T](...) and class Box[T].
Explanation
The goal is for the type checker to understand the relationship between input and output: a function that returns the first element of a list[int] must return int, not Any. A TypeVar can be limited by an upper bound or a list of allowed types. Start with simple signatures and add generics when there is a genuinely reusable contract such as a Repository or a Cache.
Code example
# Python 3.12+
def first[T](items: list[T]) -> T:
return items[0]
class Repository[T]:
def __init__(self) -> None:
self._items: dict[int, T] = {}
def get(self, key: int) -> T | None:
return self._items.get(key)
n = first([1, 2]) # Inferred type: intCommon mistakes
- Returning Any from public functions, which cancels the benefit of checking for the caller.
- Using a TypeVar that appears only once in the signature, so it ties nothing together.