Skip to content

Instantly share code, notes, and snippets.

@Tatsh
Last active October 9, 2024 04:17
Show Gist options
  • Save Tatsh/5b3d2f0dc3743538c2eba0840a10c12a to your computer and use it in GitHub Desktop.
Save Tatsh/5b3d2f0dc3743538c2eba0840a10c12a to your computer and use it in GitHub Desktop.
from collections.abc import Sequence
from typing import Protocol, Sequence, TypedDict, TypeVar, cast
class LiteralProtocol(Protocol):
__args__: Sequence[str]
class TypedDictProtocol(Protocol):
__annotations__: dict[str, LiteralProtocol]
_T = TypeVar('_T', bound=TypedDictProtocol)
def invert_dict_with_literals(td: type[_T], indices: Sequence[int] | int = 0) -> _T:
# Still must use cast(). Fundamentally it is because the bound type on _T cannot have generics.
if isinstance(indices, Sequence):
return cast(_T, {
k: v.__args__[i]
for i, (k, v) in zip(indices, td.__annotations__.items(), strict=True)
})
return cast(_T, {k: v.__args__[indices] for k, v in td.__annotations__.items()})
class ATitleTitleDescDict(TypedDict):
title: Literal['a title']
description: Literal['some description']
reveal_type(invert_dict_with_literals(ATitleTitleDescDict)) # ATitleTitleDescDict
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment