Question: I'm trying to type a function that returns a dictionary with one required key, and some additional ones. I've run into TypedDict, but it is too strict for my purpose. At the same time Dict is too lenient. To give some examples with what I have in mind: class Schema(PartiallyTypedDict): name: str year: int a: Schema = {"name": "a", "year": 1} # OK b: Schema = {"name": "a", "year": 1, rating: 5} # OK, "rating" key can be added c: Schema = {"year": 1, rating: 5} # NOT OK, "name" is missing  It would be great if there was also a way of forcing values of all of the optional/arbitrary key to be of a specific type. For example int in example above due to "rating" being one. Does there exist such a type, or is there a way of creating such a type in python typing framework?

Answer: Since PEP 655 there is a solution for this problem. In Python 3.11+ there are typing.Required and typing.NotRequired. This means we have two ways to do this. typing.Required approach  The typing.Required type qualifier is used to indicate that a variable declared in a TypedDict definition is a required key.  This means we can use the totality flag to mark any keys as not required. And then use the typing.Required to mark explicitly keys as required. from typing import TypedDict, Required class Schema(TypedDict, total=False): name: Required[str] year: Required[int] rating: int  typing.NotRequired approach  the typing.NotRequired type qualifier is used to indicate that a variable declared in a TypedDict definition is a potentially-missing key  This means we can use the totality flag to mark any keys as required and use typing.NotRequired to mark explicitly some keys as not required. from typing import TypedDict, NotRequired # total=True is the default value and therefore can be omitted. # class Schema(TypedDict, total=True): class Schema(TypedDict): name: str year: int rating: NotRequired[int]  Result Both approaches enforce dicts to have a name and a year key. It also enforces that, if a rating key is in the dict, the value is of type int. There is no restriction in adding further keys and there is no value-type restriction for those keys. This means: # OK a: Schema = {"name": "a", "year": 1} # OK, "rating" key can be added b: Schema = {"name": "a", "year": 1, rating: 5} # NOT OK, "name" is missing c: Schema = {"year": 1, rating: 5} # NOT OK, "rating" is no int d: Schema = {"name": "a", "year": 1, "rating": "invalid type"} # OK, because any (undefined) key can be added, with any type e: Schema = {"name": "a", "year": 1, "rating": 5, "undefined-key": "undefined-value-type" }   Just for completeness:  Required and NotRequired are not allowed outside of TypedDict declarations. It is allowed to have Required and NotRequired Keys in the same dict. A key can only be Required or NotRequired -> This is forbidden: Required[NotRequired[Any]]   Addendum There should be soon a way, to give type restrictions to arbitrary keys. PEP 728 brings up the extra_items parameter for TypedDict. So it should be possible to do something like: from typing import TypedDict class Schema(TypedDict(extra_items=int)): name: str year: int  Which should result in: # Ok a: Schema = {"name": "a", "year": 1, rating: 5} # Ok b: Schema = {"name": "a", "year": 1, rating: 5, another_arbitrary_key: 4} # NOT Ok, because the arbitrary rating key is no int a: Schema = {"name": "a", "year": 1, rating: "five"}  You may have expected the use of "should" this is, because at the time of writing this addendum the PEP 728 is not yet implemented.