DEV Community

ZNY
ZNY

Posted on

The Complete Guide to Python Type Hints in 2026: From Basic to Protocol Classes

The Complete Guide to Python Type Hints in 2026: From Basic to Protocol Classes

Python type hints matured significantly by 2026, with type checkers like Pyright and mypy now standard in production codebases. The combination of type hints plus a type checker catches bugs before runtime.

Here's the practical guide.

Basic Type Hints

def greet(name: str, age: int) -> str:
    return f"Hello {name}, you are {age}"

# Type aliases
UserId = int | str  # Union type
Vector = list[float]

def scale(vector: Vector, factor: float) -> Vector:
    return [x * factor for x in vector]
Enter fullscreen mode Exit fullscreen mode

Optional and None

from typing import Optional

def find_user(user_id: int) -> Optional[str]:
    user = db.get(user_id)
    return user.name if user else None

# Modern syntax (Python 3.10+)
def find_user(user_id: int) -> str | None:
    ...
Enter fullscreen mode Exit fullscreen mode

Collections

from typing import TypedDict, NamedTuple

# List of strings
def get_names() -> list[str]:
    return ["Alice", "Bob"]

# Dict with specific types
def get_user_counts() -> dict[str, int]:
    return {"alice": 10, "bob": 5}

# Set of integers
def get_ids() -> set[int]:
    return {1, 2, 3}

# Tuple with specific types
def get_coordinates() -> tuple[float, float]:
    return (40.7128, -74.0060)
Enter fullscreen mode Exit fullscreen mode

TypedDict (for dict shapes)

from typing import TypedDict

class User(TypedDict):
    id: int
    name: str
    email: str
    active: bool

def create_user(data: User) -> User:
    return data

# Type checker catches missing fields
user = create_user({"id": 1, "name": "Alice", "email": "a@b.com", "active": True})
Enter fullscreen mode Exit fullscreen mode

NamedTuple

from typing import NamedTuple

class Point(NamedTuple):
    x: float
    y: float

    def distance(self, other: "Point") -> float:
        return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5

p1 = Point(0.0, 0.0)
p2 = Point(3.0, 4.0)
print(p1.distance(p2))  # 5.0
Enter fullscreen mode Exit fullscreen mode

Protocol (structural subtyping)

from typing import Protocol

class Drawable(Protocol):
    def draw(self) -> None: ...

class Circle:
    def __init__(self, radius: float):
        self.radius = radius

    def draw(self) -> None:
        print(f"Drawing circle with radius {self.radius}")

class Square:
    def __init__(self, side: float):
        self.side = side

    def draw(self) -> None:
        print(f"Drawing square with side {self.side}")

def render(shape: Drawable) -> None:
    shape.draw()  # Works with any Drawable

render(Circle(1.0))   # OK
render(Square(1.0))    # OK
Enter fullscreen mode Exit fullscreen mode

Generics

from typing import TypeVar, Generic

T = TypeVar("T")

class Stack(Generic[T]):
    def __init__(self) -> None:
        self._items: list[T] = []

    def push(self, item: T) -> None:
        self._items.append(item)

    def pop(self) -> T:
        return self._items.pop()

    def is_empty(self) -> bool:
        return len(self._items) == 0

# Usage
stack: Stack[int] = Stack()
stack.push(1)
stack.push(2)
print(stack.pop())  # 2
Enter fullscreen mode Exit fullscreen mode

Callable Types

from typing import Callable

def apply(func: Callable[[int, int], int], a: int, b: int) -> int:
    return func(a, b)

result = apply(lambda x, y: x + y, 5, 3)  # 8
result = apply(lambda x, y: x * y, 5, 3)  # 15

# No-return callable
def log_and_execute(func: Callable[..., None], *args: object) -> None:
    print(f"Executing {func.__name__}")
    func(*args)
Enter fullscreen mode Exit fullscreen mode

Type Checking Setup

# Install pyright
pip install pyright

# Create config
# pyrightconfig.json
{
  "include": ["src"],
  "pythonVersion": "3.12",
  "typeCheckingMode": "strict"
}
Enter fullscreen mode Exit fullscreen mode
# Run type checker
pyright src/
Enter fullscreen mode Exit fullscreen mode

This article contains affiliate links. If you sign up through the links above, I may earn a commission at no additional cost to you.

Ready to Build Your Online Business?

Get started with Systeme.io for free — All-in-one platform for building your online business with AI tools.

Top comments (0)