How to Use Python Type Hints for Beginners

Build a data helper module with basic type hints — Union, Optional, List, Dict, Any, and TypeVar — to make your code clearer and safer.

Easy Python 3.9+ Aug 9, 2026 Testing & modern typing 13 views 0 copies

Python code

40 lines
Python 3.9+
from typing import Any, Union, Optional, List, Dict, Tuple, Callable, TypeVar

T = TypeVar("T")

def describe(value: Any) -> str:
    """Return a human-readable description of the value's type."""
    if isinstance(value, list):
        return f"list of {len(value)} items"
    elif isinstance(value, dict):
        return f"dict with {len(value)} keys"
    elif isinstance(value, str):
        return f"string ({len(value)} chars)"
    elif isinstance(value, (int, float)):
        return f"number: {value}"
    elif value is None:
        return "None"
    else:
        return f"instance of {type(value).__name__}"

def double(x: Union[int, float]) -> Union[int, float]:
    """Double a number."""
    return x * 2

def greet(name: Optional[str] = None) -> str:
    """Greet a person, or everyone if no name given."""
    if name is None:
        return "Hello, everyone!"
    return f"Hello, {name}!"

def process_items(items: List[int]) -> Dict[str, int]:
    """Summarize a list of numbers."""
    return {"total": sum(items), "count": len(items), "max": max(items) if items else 0}

if __name__ == "__main__":
    print(describe([1, 2, 3]))
    print(describe({"a": 1}))
    print(double(5))
    print(greet())
    print(greet("Alice"))
    print(process_items([3, 7, 2]))

Output

stdout
list of 3 items
dict with 1 keys
10
Hello, everyone!
Hello, Alice!
{'total': 12, 'count': 3, 'max': 7}

How it works

Type hints are optional annotations that tell tools like mypy and your IDE what types functions expect and return. Optional[str] is shorthand for Union[str, None], and List[int] means a list of integers. Any says 'any type is allowed' and disables checking for that value. TypeVar lets you write generic functions that work with multiple types while keeping the relationship between inputs and outputs. These hints don't change runtime behavior — they exist for documentation and static analysis.

Common mistakes

  • Forgetting `Optional` when a parameter can be `None` — use `Optional[str] = None` instead of `str = None`.
  • Using `list` instead of `List` in older Python versions — `List` works everywhere in 3.9+.
  • Type hints don't enforce anything at runtime — you still need to validate input if it comes from users.

Variations

  1. Use `from __future__ import annotations` to write hints as strings and defer evaluation, allowing built-in generics like `list[int]`.
  2. Replace `Union[int, float]` with `int | float` in Python 3.10+ for cleaner syntax.

Real-world use cases

  • Documenting function signatures in a shared library so teammates know exactly what to pass and expect back.
  • Enabling static type checking in CI with mypy to catch bugs before they reach production.
  • Improving IDE autocomplete and jump-to-definition for a large Python codebase.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from Testing & modern typing

Related tutorials and quizzes for this topic.