Type allowed keys of TypedDict

110 views Asked by At

I wonder how we should type a key, that corresponds to TypedDict instance.

Consider that there is a class, that accepts a dictionary as an input. The dictionary is typed via TypedDict. Let us say there is a method that accesses the values of the dictionary by the key. In this case the key must be a Literal containing allowed keys from the dictionary as shown in the snippet below.

from typing import Literal, TypedDict


class Data(TypedDict):
    one: str
    two: str


class MyClass:
    def __init__(self, data: Data) -> None:
        self.data = data

    def value(self, key: Literal['one', 'two']) -> str:
        return self.data[key]

But this solution is not convenient. For example, if we extend Data by adding one more key, we will have to also add it into key type annotation.

Is there a programmable way to type key?

1

There are 1 answers

3
Guillaume On

This is a really interesting question! The best way I can think of is using Annotated (see doc) this way:

from typing import Annotated


def value(self, key: Annotated[str, Data.__required_keys__ | Data.__optional_keys__]) -> str:
        return self.data[key]

This is valid syntactically and semantically, but the type checkers do not know (yet) how to parse this properly, and will just skip the second part of the annotation as fallback.