# Python Type Hints Cheat Sheet for Working Developers

> Source: <https://dev.to/syncore/python-type-hints-cheat-sheet-for-working-developers-40le>
> Published: 2026-10-19 16:38:50+00:00

3 min read · 512 words

Python’s type hinting system has evolved from a quiet PEP into an indispensable tool for growing codebases. If you are still writing raw Python without type hints, you are missing out on instant IDE feedback, bulletproof refactoring, and self-documenting code.

Let's cut the theory. Here is a practical, no-fluff cheat sheet for the type hints you will actually use in production every day.

Keep it simple. Scalars use standard Python types (`str`, `int`, `float`, `bool`), while collections require imports from the `typing` module or modern built-in generics (supported in Python 3.9+).

``` python
from typing import Dict, List, Optional, Tuple, Union

# Scalars
name: str = "Claude"
age: int = 5
is_active: bool = True
price: float = 99.9

# Collections
tags: List[str] = ["ai", "llm", "python"]
coordinates: Tuple[float, float] = (37.7749, -122.4194)
metadata: Dict[str, Union[str, int]] = {"model": "claude-opus-5", "tokens": 1000000}

# Optional values (equivalent to Type | None)
middle_name: Optional[str] = None
```

Functions are where type hints shine brightest. Always type your arguments and your return values. Use `-> None` for functions that perform side effects without returning data.

``` python
from typing import Callable, Sequence

def calculate_cost(tokens: int, rate_per_million: float) -> float:
    """Calculate API cost based on token usage."""
    return (tokens / 1_000_000) * rate_per_million

def process_batch(items: Sequence[str], callback: Callable[[str], None]) -> None:
    """Process a sequence of items and execute a callback on each."""
    for item in items:
        callback(item)

# Real-world usage with the modern Anthropic SDK
import anthropic

def generate_completion(prompt: str, model_id: str = "claude-opus-5") -> str:
    client = anthropic.Anthropic()
    response = client.messages.create(
        model=model_id,
        max_tokens=4000,
        messages=[{"role": "user", "content": prompt}],
    )
    # Extract text from the response content blocks safely
    return "".join(block.text for block in response.content if block.type == "text")
```

When your codebase grows, strict class hierarchies can slow you down. Use `Protocol` for structural subtyping (duck typing with type safety) and `TypedDict` for structured JSON payloads.

``` python
from typing import Protocol, TypedDict

# Protocol: Any object with a 'generate' method matches this type
class LLMProvider(Protocol):
    def generate(self, prompt: str) -> str:
        ...

# TypedDict: Perfect for validating API payloads and config dictionaries
class APIConfig(TypedDict):
    model: str
    max_tokens: int
    thinking_enabled: bool

def configure_request(config: APIConfig) -> None:
    print(f"Configuring request for model: {config['model']}")

# Valid dictionary matching TypedDict structure
my_config: APIConfig = {
    "model": "claude-sonnet-5",
    "max_tokens": 8000,
    "thinking_enabled": True
}

configure_request(my_config)
```

`mypy --strict your_module.py` to your CI/CD pipeline to catch type errors before they hit production.`list[str]` over `List[str]` and `str | None` over `Optional[str]` if you are running Python 3.10+.`Any` temporarily—just don't leave it there permanently.
What is your favorite advanced typing pattern in Python? Drop a comment below with your go-to trick or headache. If you found this cheat sheet helpful, hit the bookmark button and share it with your team!
