g.pickardou
g.pickardou

Reputation: 35812

How to have optional keys in TypedDict?

I am trying to create a TypedDict with optional keys but neither Optional neither NotRequired does not work. (I tried NotRequired based on this SO answer)

class MyTypedDict(TypedDict):
    my_key1: Optional[int]
    my_key2: NotRequired[int]

my_variable = MyTypedDict()

For both keys I got Parameter 'my_key1' unfilled and Parameter 'my_key2' unfilled

What am I missing?

Upvotes: 9

Views: 6133

Answers (2)

d-k-bo
d-k-bo

Reputation: 662

NotRequired is exactly what you are looking for. Optional[int] means int | None, but the item is still required. Any item that is annotated as NotRequired[int] can be ommitted as stated in PEP 655.

Note: If you import Required or NotRequired from typing_extensions (on Python <3.11), you should also import TypedDict from typing_extensions.

So if your type-checker supports this feature, it should only complain about missing my_key1.

# Python >= 3.11
from typing import Optional, NotRequired, TypedDict

# Python < 3.11
from typing import Optional
from typing_extensions import NotRequired, TypedDict


class MyTypedDict(TypedDict):
    my_key1: Optional[int]
    my_key2: NotRequired[int]

my_variable = MyTypedDict()
# mypy error: Missing key "my_key1" for TypedDict "MyTypedDict"
# pyright error: Argument missing for parameter "my_key1"

Upvotes: 20

joel
joel

Reputation: 7867

You can mix required and optional values with inheritance and total. From the mypy docs

class MovieBase(TypedDict):
    name: str
    year: int

class Movie(MovieBase, total=False):
    based_on: str

Movie has required keys name and year, while based_on can be left out when constructing an object

Upvotes: 3

Related Questions