What are type hints in Python and why should you use them?
Type hints (PEP 484, Python 3.5+) are optional annotations that indicate the expected types of variables, function parameters, and return values. They do not enforce types at runtime -- Python remains dynamically typed. Instead, they serve as documentation and enable static analysis tools like mypy to catch type errors before running the code.
Benefits:
- Catch bugs early: Static analyzers find type mismatches before runtime.
- Better IDE support: Autocomplete, refactoring, and inline documentation.
- Living documentation: Types communicate intent more precisely than comments.
- Easier refactoring: Changing a type signature immediately reveals all affected call sites.
Basic syntax:
- Parameters:
def func(name: str, age: int) -> bool: - Variables:
count: int = 0 - No effect at runtime:
def add(x: int, y: int) -> int:happily accepts strings.
1. Annotate function parameters with : type
2. Annotate return type with -> type
3. Annotate variables with : type = value
4. Run mypy to check types statically
5. Types are ignored at runtime (no performance cost)
# Basic type hints
def greet(name: str) -> str:
return f"Hello, {name}!"
def add(x: int, y: int) -> int:
return x + y
# Variable annotations
count: int = 0
name: str = "Alice"
prices: list[float] = [9.99, 19.99, 29.99]
# Python 3.9+ built-in generics
def process_items(items: list[str]) -> dict[str, int]:
return {item: len(item) for item in items}
# Python 3.10+ union with |
def parse_id(value: int | str) -> int:
return int(value)
# Type hints are NOT enforced at runtime
result = add("hello", "world") # No runtime error!
print(result) # "helloworld"
# But mypy would flag: error: Argument 1 has incompatible type "str"; expected "int"
# Checking annotations at runtime (metadata only)
print(greet.__annotations__)
# {'name': <class 'str'>, 'return': <class 'str'>}
# None return type
def log_message(msg: str) -> None:
print(msg)
# Complex types
def find_user(users: list[dict[str, str]], name: str) -> dict[str, str] | None:
for user in users:
if user.get('name') == name:
return user
return None
- •Type hints are optional annotations; they do NOT enforce types at runtime
- •Use : for parameter/variable types and -> for return types
- •Python 3.9+ supports list[int], dict[str, int] directly (no import needed)
- •Python 3.10+ supports X | Y syntax instead of Union[X, Y]
- •mypy is the primary static type checker for Python
- •Type hints have zero runtime enforcement; passing wrong types still works
- •list[int] syntax requires Python 3.9+; use typing.List[int] for older versions
- •Annotations are stored in __annotations__ and can slightly increase import time