mypy icon indicating copy to clipboard operation
mypy copied to clipboard

Typeguard for TypedDict keys

Open tlambert03 opened this issue 4 years ago • 3 comments

Feature

I don't know enough to say whether this is a mypy request or a typing module request... but I find myself doing this pattern to avoid the error TypedDict key must be a string literal; expected one of ("a", "b") [misc]

class MyDict(TypedDict, total=False):
    a: int
    b: str
    ...

MyDictKeys = Union[Literal['a'], Literal['b']]

def is_mydict_key(key: str) -> TypeGuard[WidgetOptionKeys]:
    return key in MyDictKeys.__annotations__

Pitch

not sure how it would be implemented (or if it already is!) ... but it would be nice to have a way to type narrow a key without having to duplicate all of the keys in a TypedDict in a separate Union of Literals

tlambert03 avatar Nov 14 '21 16:11 tlambert03

You can use Literal['a', 'b'] to shorten the code a bit, but I see what you mean....

mypy could probably add something where if k in n infers k is a key of n... Probably? I think there's actually already a feature request here for that, but I suspect TypedDict would have to be special-cased in some way lol

A5rocks avatar Nov 15 '21 03:11 A5rocks

mypy could probably add something where if k in n infers k is a key of n... Probably? I think there's actually already a feature request here for that, but I suspect TypedDict would have to be special-cased in some way lol

This is the relevant feature request:

  • #9953

AlexWaygood avatar May 03 '22 14:05 AlexWaygood

Typescript has a keyOf operator: https://www.typescriptlang.org/docs/handbook/2/keyof-types.html

But to make that work here it could be something like:

class MyDict(TypedDict, total=False):
    a: int
    b: str

def is_mydict_key(key: KeyOf[MyDict]) -> TypeGuard[WidgetOptionKeys]:
    return key in MyDictKeys.__annotations__

Obviously is_mydict_key is a bit useless in this example since mypy would already complain if its not a key.

KeyOf[MyDict] would 'desugar' to Literal['a', 'b']

hmvp avatar Aug 08 '22 10:08 hmvp