GGistDev

Type Hints in Python

Type hints add optional static typing using annotations checked by tools like mypy/pyright.

Function and variable annotations

Annotate parameters, returns, and variables.

from typing import List

def add(a: int, b: int) -> int: ...
count: int = 0
names: List[str] = ["Ada", "Guido"]

Unions and Optionals (PEP 604)

Use | for unions and | None for optionals.

from typing import Optional

val: int | str
maybe: Optional[int] = None      # same as int | None

Literals and enums

Constrain to specific values.

from typing import Literal
role: Literal["user", "admin"]

Generics and TypeVars

Write generic functions and classes.

from typing import TypeVar, Iterable, Sequence
T = TypeVar('T')

def first(xs: Sequence[T]) -> T: return xs[0]

Protocols and structural typing

Protocols specify required methods; any type matching the method set is accepted.

from typing import Protocol
class SupportsClose(Protocol):
    def close(self) -> None: ...

def cleanup(x: SupportsClose) -> None:
    x.close()

TypedDict and dataclasses

Model dict‑like records with TypedDict or use @dataclass for structured types.

from typing import TypedDict
class UserTD(TypedDict):
    id: int
    name: str

NewType and type aliases

NewType provides distinct nominal types; aliases improve readability.

from typing import NewType
UserId = NewType("UserId", int)
JSON = dict[str, object]

Any and cast

Use Any sparingly; prefer precise types. Use cast for narrowing when the checker cannot infer.

from typing import Any, cast
x: Any = fetch()
y = cast(str, x)

Best practices

  • Add hints to public APIs first; annotate gradually
  • Prefer precise, readable types over overly clever expressions
  • Keep runtime behavior unchanged; hints are for tooling

Summary

  • Use annotations, unions, generics, and protocols to document and check intent
  • Favor gradual typing and clear models (TypedDict, dataclasses)