Type Hints
Miss your compiler? Good news — Python can have compile-time safety too. Optional, gradual, and free.
▶ Watch this reelWhat you'll learn
- Basic hints
- Optional & Union
- Generics & TypedDict
- mypy / pyright
Remember this
- Hints: name: type -> return; collections parameterize as list[str]
- Optional[str] = str | None — declare None or the checker complains at callers
- TypedDict for dict-shaped data; mypy/pyright in editor + CI, tighten gradually
Basics
def f(name: str, n: int = 1) -> str:— params + return.- Collections parameterize:
list[str],dict[str, int],tuple[str, int]. - Modern (3.9+): lowercase builtins; legacy code uses
typing.Listetc.
Optional & Union
Optional[str]≡str | None— None must be declared.str | int(3.10+) /Union[str, int].- Narrow with
if x is not None:/isinstance(...)— checkers understand guards.
Generics & TypedDict
def first[T](items: list[T]) -> T: # 3.12+ (TypeVar before 3.12)
return items[0]
class ApiResponse(TypedDict):
model: str
tokens: int
- TypedDict = dict with a schema (JSON land) · dataclass/Pydantic = real objects.
mypy / pyright
- Editor: pyright (Pylance) · CI:
mypy src/(fail build on errors). - Adopt gradually: loose →
disallow_untyped_defs→ strict.
Code: Type hints that earn their keep
from typing import TypedDict, Optional
# --- basics ---------------------------------------------------
def estimate_cost(model: str, tokens: int) -> float:
prices: dict[str, float] = {"gpt-4o": 2.50, "sonnet": 3.00}
return tokens / 1_000_000 * prices.get(model, 1.00)
# --- Optional: None must be declared ---------------------------
def find_model(name: str) -> Optional[str]:
return name if name.startswith("gpt") else None
m = find_model("gpt-4o")
if m is not None: # narrowing — mypy verifies this guard
print(m.upper())
# --- TypedDict: schemas for dict-shaped data -------------------
class ChatMessage(TypedDict):
role: str
content: str
class ApiResponse(TypedDict):
model: str
message: ChatMessage
tokens: int
payload: ApiResponse = {
"model": "gpt-4o",
"message": {"role": "assistant", "content": "hi"},
"tokens": 12,
}
# --- check -----------------------------------------------------
# $ pip install mypy
# $ mypy --ignore-missing-imports src/
# CI: mypy src/ && pytest # types gate + tests gate