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