Zet - How do I narrow a type in Python?

How do I narrow a type in Python?

The Problem

Type checkers don’t always know that a variable is no longer None after a check.

x: str | None = get_value()
# x is str | None here
if x is not None:
    # x is still str | None to the type checker
    print(x.upper())  # Error!

Solution 1: Reassign

x: str | None = get_value()
if x is not None:
    x = x  # Narrow to str
    print(x.upper())

Solution 2: Type Guard / Helper Function

def _check(x: str | None) -> str:
    if x is None:
        raise ValueError("Expected non-None")
    return x

Solution 3: assert

x: str | None = get_value()
assert x is not None
print(x.upper())  # OK

Solution 4: Type Narrowing with isinstance

x: int | str = get_value()
if isinstance(x, int):
    # x is int here
    print(x + 1)

Solution 5: Literal Types

def process(status: Literal["loading", "success", "error"]):
    if status == "loading":
        # status is Literal["loading"]
        ...

#python #types