TypeGuard narrows types in type checking with custom functions.
1from typing import TypeGuard23def is_string_list(val: list[any]) -> TypeGuard[list[str]]:4 return all(isinstance(x, str) for x in val)56def process(data: list[any]):7 if is_string_list(data):8 # Type checker knows data is list[str] here9 print(" ".join(data)) # No warning!10 else:11 # data is still list[any]12 print(data)1314# With Pydantic15from pydantic import BaseModel1617class Success(BaseModel):18 status: str = "ok"19 data: dict2021class Error(BaseModel):22 status: str = "error"23 message: str2425def is_success(response: Success | Error) -> TypeGuard[Success]:26 return response.status == "ok"2728def handle_response(response: Success | Error):29 if is_success(response):30 print(response.data) # Type checker knows it's Success31 else:32 print(response.message) # Type checker knows it's Error
Benefits: