typing_extensions で利用可能な型ヒントの一覧

# これは何？

`typing-extensions` は Python 標準ライブラリ `typing` のバックポートです。
たとえば、 Python==3.11 で追加された型ヒントを、 Python<3.11 でも利用したい場合、
`typing-extensions` をインストールしてこちらから import すれば利用できます。

この記事では以下についてまとめています。

- どの型ヒントがバックポートされているのか
- 特定の型ヒントが実装されたのはどのバージョンからか

`typing-extensions>=4` であれば [CHANGELOG.md](https://github.com/python/typing_extensions/blob/main/CHANGELOG.md) を読めばわかります
`typing-extensions<4` では、まとまった情報が無いように見えたので、抽出したものをまとめておきます。

# History of `typing_extensions`
## `typing_extensions.Annotated`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.Any`

- Added [typing-extensions==4.4.0](https://pypi.org/project/typing-extensions/4.4.0/)

## `typing_extensions.AsyncContextManager`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.AsyncGenerator`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.AsyncIterable`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.AsyncIterator`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Awaitable`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Callable`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.ChainMap`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.ClassVar`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Concatenate`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.ContextManager`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Coroutine`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Counter`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.DefaultDict`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Deque`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Final`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.Generic`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.GenericMeta`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.HAVE_ANNOTATED`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.HAVE_PROTOCOLS`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.IntVar`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.KT`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Literal`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.LiteralString`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.NamedTuple`

- Added [typing-extensions==4.3.0](https://pypi.org/project/typing-extensions/4.3.0/)

## `typing_extensions.Never`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.NewType`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.NoReturn`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.NotRequired`

- Added [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.OLD_GENERICS`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.OrderedDict`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.PEP_560`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.ParamSpec`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.ParamSpecArgs`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.ParamSpecKwargs`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.Protocol`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Required`

- Added [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.SUBS_TREE`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.Self`

- Added [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.SupportsIndex`

- Added [typing-extensions==3.7.4.3](https://pypi.org/project/typing-extensions/3.7.4.3/)

## `typing_extensions.T`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.TYPE_CHECKING`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.T_co`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.T_contra`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Text`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.Tuple`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.Type`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.TypeAlias`

- Added [typing-extensions==3.7.4.3](https://pypi.org/project/typing-extensions/3.7.4.3/)

## `typing_extensions.TypeGuard`

- Added [typing-extensions==3.10.0.0](https://pypi.org/project/typing-extensions/3.10.0.0/)

## `typing_extensions.TypeVar`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)
- Added [typing-extensions==4.4.0](https://pypi.org/project/typing-extensions/4.4.0/)

## `typing_extensions.TypeVarTuple`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.TypedDict`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.TypingMeta`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.Unpack`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.VT`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.VT_co`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.V_co`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)
- Removed [typing-extensions==4.0.0](https://pypi.org/project/typing-extensions/4.0.0/)

## `typing_extensions.assert_never`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.assert_type`

- Added [typing-extensions==4.2.0](https://pypi.org/project/typing-extensions/4.2.0/)

## `typing_extensions.clear_overloads`

- Added [typing-extensions==4.2.0](https://pypi.org/project/typing-extensions/4.2.0/)

## `typing_extensions.dataclass_transform`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.final`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.get_args`

- Added [typing-extensions==3.7.4.2](https://pypi.org/project/typing-extensions/3.7.4.2/)

## `typing_extensions.get_origin`

- Added [typing-extensions==3.7.4.2](https://pypi.org/project/typing-extensions/3.7.4.2/)

## `typing_extensions.get_overloads`

- Added [typing-extensions==4.2.0](https://pypi.org/project/typing-extensions/4.2.0/)

## `typing_extensions.get_type_hints`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

## `typing_extensions.is_typeddict`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.overload`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.override`

- Added [typing-extensions==4.4.0](https://pypi.org/project/typing-extensions/4.4.0/)

## `typing_extensions.reveal_type`

- Added [typing-extensions==4.1.0](https://pypi.org/project/typing-extensions/4.1.0/)

## `typing_extensions.runtime`

- Added [typing-extensions==3.6.5](https://pypi.org/project/typing-extensions/3.6.5/)

## `typing_extensions.runtime_checkable`

- Added [typing-extensions==3.7.4](https://pypi.org/project/typing-extensions/3.7.4/)

# 抽出用スクリプト

- PyPI の #history ページから バージョン番号を昇順に集める
- バージョン番号ごとに仮想環境を作る
  - `typing_extensions` をインストールする
  - 仮想環境で `typing_extensions` をインポートして、要素の一覧を出す
- 要素ごとに追加/削除されたバージョンをリンク付きで書きだす

```python3
from typing import NewType
from aiohttp import ClientSession
from contextlib import AsyncExitStack
from lxml import html
from collections.abc import AsyncIterator
from asyncio import run, gather, create_subprocess_exec
from functools import partial
from tempfile import TemporaryDirectory
from pathlib import Path
import sys
from subprocess import PIPE
from functools import reduce
from operator import or_

URI = NewType("URI", str)
VersionString = NewType("VersionString", str)


async def main():
    package = "typing-extensions"
    _get_attributes = partial(get_attributes, package)

    items = await gather(
        *map(
            _get_attributes,
            [version async for version in get_versions(package)],
        )
    )
    versions_and_attrs = {key: value for key, value in items if value is not None}
    all_attrs = reduce(or_, versions_and_attrs.values())

    for attr in sorted(all_attrs):
        print(f"## `typing_extensions.{attr}`")
        print()
        prev_exists = False
        for version, attrs in versions_and_attrs.items():
            exists = attr in attrs
            if exists != prev_exists:
                if exists:
                    print(
                        f"- Added [{package}=={version}](https://pypi.org/project/typing-extensions/{version}/)"
                    )
                else:
                    print(
                        f"- Removed [{[package]}=={version}](https://pypi.org/project/typing-extensions/{version}/)"
                    )

            prev_exists = exists
        print()


async def get_element(uri: URI):
    async with AsyncExitStack() as stack:
        aenter = stack.enter_async_context
        session = await aenter(ClientSession())
        response = await aenter(session.get(uri))
        return html.fromstring(await response.text())


async def get_versions(package: str) -> AsyncIterator[VersionString]:
    root = await get_element(f"https://pypi.org/project/{package}/#history")
    versions = list(root.xpath('//p[@class="release__version"]/text()'))
    for version in reversed(versions):
        yield version.strip()


async def get_attributes(
    package: str, version: VersionString
) -> tuple[VersionString, list[str]]:
    async with AsyncExitStack() as stack:
        aenter = stack.enter_async_context
        enter = stack.enter_context
        directory = Path(enter(TemporaryDirectory()))

        venv_cmd = [sys.executable, "-m", "venv", f"{directory}"]
        print(*venv_cmd, sep=" ")
        venv = await create_subprocess_exec(*venv_cmd)
        assert await venv.wait() == 0

        (executable,) = directory.rglob("python")

        pip_upgrade_cmd = [f"{executable}", "-m", "pip", "install", "--upgrade", "pip"]
        print(*pip_upgrade_cmd, sep=" ")
        pip_upgrade = await create_subprocess_exec(*pip_upgrade_cmd)
        assert await pip_upgrade.wait() == 0

        package_install_cmd = [
            f"{executable}",
            "-m",
            "pip",
            "install",
            f"{package}=={version}",
        ]
        print(*package_install_cmd, sep=" ")
        package_install = await create_subprocess_exec(*package_install_cmd)
        assert await package_install.wait() == 0

        listup_cmd = [
            f"{executable}",
            "-c",
            r"""\
import typing_extensions
from types import ModuleType
for attr in dir(typing_extensions):
    obj = getattr(typing_extensions, attr)
    if attr.startswith("_") or isinstance(obj, ModuleType):
        continue
    print(attr)
""",
        ]
        listup = await create_subprocess_exec(*listup_cmd, stdout=PIPE)
        stdout, _ = await listup.communicate()
        if listup.returncode != 0:
            return version, None
        else:
            return version, set(stdout.decode("utf-8").splitlines(keepends=False))


if __name__ == "__main__":
    run(main())
```