the full guide

Advanced typing

Beyond basic hints, Python's typing system supports optional values (str | None), generics (a list of a certain type), Protocols (a required shape), TypedDict and more. A static checker such as mypy or Pyright uses these to find bugs without running the code.

8 min Advanced

What you need: The earlier topics of this module, and its prerequisites.

Definition

Beyond basic hints, Python's typing system supports optional values (str | None), generics (a list of a certain type), Protocols (a required shape), TypedDict and more. A static checker such as mypy or Pyright uses these to find bugs without running the code.

In simple words

Plain hints say "this is a list". Advanced ones say "this is a list of students, and this function returns the same type it was given". The more exact the description, the more mistakes a checker can catch.

Why it matters

Large codebases rely on this to stay safe to change. LLM libraries also use it: Pydantic turns type hints into validation and into schemas for tool calling.

How it works

HintMeans
str | NoneA string or None
list[int]A list of ints
dict[str, float]String keys, float values
Callable[[int], str]A function from int to str
Literal['a', 'b']Only these values
ProtocolAnything with this shape
TypedDictA dict with known keys

In code

typing_demo.py
from typing import Literal, Protocol, TypedDict, TypeVar

T = TypeVar("T")

def first(items: list[T]) -> T | None:
    return items[0] if items else None

class Student(TypedDict):
    name: str
    mark: int

class Predictor(Protocol):
    def predict(self, x: float) -> float: ...

class Doubler:                       # no inheritance is needed
    def predict(self, x: float) -> float:
        return x * 2

def run(model: Predictor, mode: Literal["fast", "slow"]) -> float:
    return model.predict(2.0)

print(first([1, 2]), first([]))
riya: Student = {"name": "Riya", "mark": 90}
print(riya["mark"])
print(run(Doubler(), "fast"))

Output

1 None
90
4.0

Common mistakes

  • Overusing Any. It switches off checking wherever it spreads.
  • Assuming hints validate at run time. Use Pydantic when you need that.

Check yourself

Question 1

1. What does str | None mean?

Question 2

2. What does a Protocol check?

Summary

  • Precise hints catch more bugs before you run the code.
  • mypy or Pyright do the checking.

Finished reading?

Sources: Python docs: typing