Modern Type Hints & Static Type Checking
Transform Python into a strictly contract-driven language. Master modern Union syntax, Generics, Protocols, TypedDict, and automated mypy / pyright static analysis.
Implicit Dynamic Typing vs Modern Python 3.10+ Type Contracts
Implicit code causes runtime `NoneType` bugs. Strict type hints allow IDE auto-completion and enable automated static type checkers (`mypy`, `pyright`).
# ❌ What types does this take? What does it return?
def process_user_data(user_id, flags):
user = fetch_user(user_id)
if not user:
return None
return user.compute_scores(flags)
# ✅ Modern Union syntax (User | None) & built-in generics
def process_user_data(
user_id: int,
flags: list[str]
) -> ScoreResult | None:
user: User | None = fetch_user(user_id)
return user.compute_scores(flags) if user else None
📚 Essential Python Typing Constructs
list[str], dict[str, int]
Native built-in generics in Python 3.9+ without importing `typing`.
User | None (Union)
Modern Python 3.10+ pipe operator replacing legacy `Optional[User]`.
Literal["admin", "user"]
Restricts string or integer variables to exact value choices.
TypeAlias
Assigns readable explicit names to complex generic types.
TypedDict
Types dictionary structure payloads without instantiating class objects.
Protocol
Structural subtyping (duck typing contracts) without explicit inheritance.
TypeVar & Generic[T]
Builds reusable generic classes, collections, and repository interfaces.
Callable[[int], bool]
Annotates function callback parameter signatures and return types.
💻 Production Blueprint: Advanced Type Hints & Generic Repositories
See how `TypeVar`, `Generic`, `TypedDict`, and `Protocol` create robust, type-checked Python applications.
from typing import TypeVar, Generic, Literal, TypedDict, Protocol, TypeAlias
# 1. TypeAlias & Literal Types
UserId: TypeAlias = int
Role: TypeAlias = Literal["admin", "user", "guest"]
# 2. TypedDict Structure
class UserPayload(TypedDict):
sub: str
role: Role
# 3. Protocol (Duck Typing Contract)
class Renderable(Protocol):
def render(self) -> str:
...
# 4. Generic Repository Contract
T = TypeVar("T")
class GenericRepository(Generic[T]):
def __init__(self) -> None:
self._store: dict[UserId, T] = {}
def get_by_id(self, entity_id: UserId) -> T | None:
return self._store.get(entity_id)