๐Ÿ“Type Annotations: list, dict, Optional, Union, AnyLESSON

Type Annotations: list, dict, Optional, Union, Any

Python is dynamically typed โ€” you don't have to declare types. But type hints let you annotate your code with type information that static analysis tools (mypy, pyright, Pylance) can check, IDEs can use for autocompletion, and readers can use to understand intent. Crucially, they are not enforced at runtime.

Basic Variable Annotations

Function Parameter and Return Types

list[int], dict[str, int] โ€” Generic Types (Python 3.9+)

Since Python 3.9, you can use built-in types directly as generics. Before 3.9, you had to import List, Dict, etc. from typing:

Optional[str] โ€” Values That Can Be None

Optional[X] is shorthand for Union[X, None] โ€” the value is either X or None:

Union[int, str] โ€” Multiple Possible Types

Union[X, Y] means the value can be either X or Y:

Any โ€” Opt Out of Type Checking

Any is compatible with every type. Use it sparingly โ€” overusing Any defeats the purpose of type hints:

tuple[int, ...] and Callable

Type Aliases

Give complex types a name for readability:

TypedDict โ€” Typed Dictionaries

When a dict has a fixed structure (like a JSON object), TypedDict describes it precisely:

from future import annotations โ€” Deferred Evaluation

For forward references and performance, you can defer evaluation of annotations (all become strings at definition time):

Runtime vs Static โ€” Hints Are Not Enforced

Type hints are documentation for tools, not runtime enforcement:

Use mypy or pyright for static checking:

Knowledge Check

What does `Optional[str]` mean in type hints?

In Python 3.9+, how do you annotate a list of integers without importing from `typing`?

What happens at runtime if you pass a string to a function annotated to accept `int`?