typing-extensions

raw JSON →
4.15.0 verified Tue May 12 auth: no python install: verified quickstart: verified

typing-extensions provides backported and experimental type hints for Python, serving two purposes: enabling use of new type system features on older Python versions (e.g., TypeGuard from 3.10 is available on 3.9+), and enabling experimentation with new PEP-proposed typing constructs before they land in the standard library. The library also re-exports all names from the standard typing module, so it can serve as a single import source. Current version is 4.15.0 (as of early 2026); feature releases follow an irregular cadence under Semantic Versioning where only the major version is bumped for breaking changes.

pip install typing-extensions
error ModuleNotFoundError: No module named 'typing_extensions'
cause The typing-extensions package is not installed in the current Python environment.
fix
pip install typing-extensions
error ImportError: cannot import name 'TypeGuard' from 'typing'
cause TypeGuard was introduced in Python 3.10; on older Python versions, it must be imported from typing_extensions.
fix
from typing_extensions import TypeGuard
error ImportError: cannot import name 'Self' from 'typing'
cause Self (from PEP 673) was introduced in Python 3.11; on older Python versions, it must be imported from typing_extensions.
fix
from typing_extensions import Self
error ImportError: cannot import name 'TypeAlias' from 'typing'
cause TypeAlias (from PEP 613) was introduced in Python 3.10; on older Python versions, it must be imported from typing_extensions.
fix
from typing_extensions import TypeAlias
breaking Python 3.8 support dropped in 4.14.0. Projects that still run on CPython/PyPy 3.8 must pin to typing_extensions<4.14.
fix Pin `typing-extensions~=4.13` for Python 3.8 environments, or upgrade Python.
breaking typing.ByteString is not re-exported and is removed in Python 3.14. Any code that relied on typing_extensions re-exporting ByteString will break.
fix Replace `typing.ByteString` or `typing_extensions.ByteString` with `typing_extensions.Buffer` (equivalent to `collections.abc.Buffer` on 3.12+).
breaking TypedDict keyword-argument construction syntax (e.g., `Movie = TypedDict('Movie', title=str)`) emits DeprecationWarning on Python 3.12 and raises TypeError on Python 3.13+.
fix Use the class-based TypedDict syntax: `class Movie(TypedDict): title: str`.
breaking typing_extensions does not re-export names removed from typing, including the anticipated removal of `typing.no_type_check_decorator` in Python 3.15. Importing it from typing_extensions will raise ImportError on 4.14+.
fix Stop using `no_type_check_decorator`; it is unsupported by type checkers and has no maintained replacement.
gotcha Pinning to `typing-extensions~=x.y.z` (patch-level) defeats Semantic Versioning and can block important bugfixes. The correct specifier is `typing-extensions~=x.y` (minor-level) or `>=x.y,<(x+1)`.
fix Use `typing-extensions~=4.14` (or whichever minor first includes your needed features), not `==4.14.1`.
gotcha When introspecting types at runtime (e.g., `isinstance(obj, some_protocol)`), always check for both `typing.X` and `typing_extensions.X` variants. Future releases may re-export a separate backport version that is not `is`-identical to the stdlib one.
fix Use `isinstance(obj, (typing.X, typing_extensions.X))` or compare with `in (typing.X, typing_extensions.X)` in runtime isinstance/issubclass guards.
gotcha `deprecated` (PEP 702) was added in 4.5.0 but many ecosystems (FastAPI, Pydantic) require >=4.8.0. Environments with conda-pinned or transitive older typing_extensions produce `ImportError: cannot import name 'deprecated'`.
fix Ensure `typing-extensions>=4.8.0` is in your dependency list; audit layered environments (Docker layers, conda + pip) for duplicate installs at different versions.
pip install 'typing-extensions~=4.15'
python os / libc variant status wheel install import disk
3.10 alpine (musl) 'typing-extensions~=4.15' - - 0.02s 18.1M
3.10 alpine (musl) typing-extensions - - 0.02s 18.1M
3.10 slim (glibc) 'typing-extensions~=4.15' - - 0.01s 19M
3.10 slim (glibc) typing-extensions - - 0.01s 19M
3.11 alpine (musl) 'typing-extensions~=4.15' - - 0.06s 19.9M
3.11 alpine (musl) typing-extensions - - 0.06s 19.9M
3.11 slim (glibc) 'typing-extensions~=4.15' - - 0.04s 20M
3.11 slim (glibc) typing-extensions - - 0.04s 20M
3.12 alpine (musl) 'typing-extensions~=4.15' - - 0.06s 11.8M
3.12 alpine (musl) typing-extensions - - 0.05s 11.8M
3.12 slim (glibc) 'typing-extensions~=4.15' - - 0.05s 12M
3.12 slim (glibc) typing-extensions - - 0.05s 12M
3.13 alpine (musl) 'typing-extensions~=4.15' - - 0.04s 11.4M
3.13 alpine (musl) typing-extensions - - 0.04s 11.4M
3.13 slim (glibc) 'typing-extensions~=4.15' - - 0.04s 12M
3.13 slim (glibc) typing-extensions - - 0.04s 12M
3.9 alpine (musl) 'typing-extensions~=4.15' - - 0.02s 17.6M
3.9 alpine (musl) typing-extensions - - 0.02s 17.6M
3.9 slim (glibc) 'typing-extensions~=4.15' - - 0.02s 18M
3.9 slim (glibc) typing-extensions - - 0.02s 18M

Demonstrates the most commonly used constructs: TypedDict with ReadOnly/NotRequired fields, TypeAlias, Self, runtime_checkable Protocol, TypeIs narrowing, the @deprecated decorator, and @override.

from typing_extensions import (
    TypedDict,
    NotRequired,
    ReadOnly,
    Annotated,
    Self,
    TypeAlias,
    override,
    deprecated,
    TypeIs,
    Protocol,
    runtime_checkable,
)
import sys

# TypedDict with optional and read-only fields (PEP 655, PEP 705)
class Movie(TypedDict):
    title: ReadOnly[str]
    year: NotRequired[int]

movie: Movie = {"title": "Blade Runner"}

# TypeAlias for clarity
Vector: TypeAlias = list[float]

# Self in method signatures
class Builder:
    def set_name(self, name: str) -> Self:
        self.name = name
        return self

# Protocol with runtime checking
@runtime_checkable
class Drawable(Protocol):
    def draw(self) -> None: ...

# TypeIs for narrowing
def is_str_list(val: list[object]) -> TypeIs[list[str]]:
    return all(isinstance(x, str) for x in val)

# deprecated decorator
@deprecated("Use new_api() instead")
def old_api() -> None:
    pass

# override for subclass safety
class Base:
    def compute(self) -> int:
        return 0

class Child(Base):
    @override
    def compute(self) -> int:
        return 42

print(f"typing_extensions quickstart OK — Python {sys.version}")