Type Hints & the typing Module
Type Hints & the typing Module
Section titled “Type Hints & the typing Module”Simple Analogy 🏷️
Section titled “Simple Analogy 🏷️”Imagine a mailbox labeled “Letters Only” — anyone who posts a package knows not to put it there. Type hints are like labels on your code that tell readers (and tools) what kind of data to expect.
Why Type Hints?
Section titled “Why Type Hints?”Python is dynamically typed — variables can hold any type. Type hints add optional annotations that:
- Make code self-documenting — you know what a function expects and returns
- Enable editor autocomplete — VS Code, PyCharm suggest correct methods
- Catch bugs early —
mypyfinds type errors before runtime - Help teammates — clear contracts for what functions do
Basic Annotations
Section titled “Basic Annotations”# Variable annotationsname: str = "Alice"age: int = 30is_active: bool = Truepi: float = 3.14159
# Function annotationsdef greet(name: str) -> str: return f"Hello, {name}!"Collections
Section titled “Collections”from typing import List, Dict, Tuple, Set
# Python 3.9+ — use built-ins directlynumbers: list[int] = [1, 2, 3]user_map: dict[str, int] = {"Alice": 30, "Bob": 25}coords: tuple[float, float] = (40.7128, -74.006)unique: set[str] = {"apple", "banana"}
# Python 3.8 and below — use typing modulenumbers: List[int] = [1, 2, 3]user_map: Dict[str, int] = {"Alice": 30}Optional and Union
Section titled “Optional and Union”from typing import Optional, Union
# Optional = the value can be Nonedef find_user(user_id: int) -> Optional[str]: """Returns None if user not found.""" if user_id == 1: return "Alice" return None # ✅ Allowed
# Union = multiple possible typesdef process_value(value: Union[int, str]) -> str: if isinstance(value, int): return f"Number: {value}" return f"Text: {value}"
# Python 3.10+ shorthanddef process(value: int | str) -> str: ...def find(user_id: int) -> str | None: ...Callable (Functions as Arguments)
Section titled “Callable (Functions as Arguments)”from typing import Callable
# A function that takes an int and returns a strFormatter = Callable[[int], str]
def apply_formatter(value: int, formatter: Formatter) -> str: return formatter(value)
def format_as_currency(n: int) -> str: return f"${n:,}"
print(apply_formatter(1000, format_as_currency)) # $1,000Custom Types with TypeAlias
Section titled “Custom Types with TypeAlias”from typing import TypeAlias
# Give a meaningful name to a complex typeUserId: TypeAlias = intUserData: TypeAlias = dict[str, Union[str, int, list[str]]]
def get_user(user_id: UserId) -> UserData: return {"name": "Alice", "age": 30, "tags": ["admin"]}Running mypy
Section titled “Running mypy”# Installpip install mypy
# Check a filemypy myfile.py
# Strict mode — catches more issuesmypy --strict myfile.py# mypy catches this:def add(a: int, b: int) -> int: return a + b
add("hello", 5) # ❌ mypy: Argument 1 has incompatible type "str"🧠 In Simple Words
Section titled “🧠 In Simple Words”- Type hints are optional labels that describe what types a variable/function expects
- Use
list[int],dict[str, int]for collections (Python 3.9+) Optional[x]= the value can bexorNoneUnion[x, y]= the value can bexoryCallable[[ArgType], ReturnType]= describes a function signature- Run
mypyto catch type errors before the code runs