Skip to content

TypedDict does not support type refinement in subclasses #7435

@sm-Fifteen

Description

@sm-Fifteen

Are you reporting a bug, or opening a feature request?

Feature Request

Please insert below the code you are checking with mypy.

from typing_extensions import Literal, TypedDict
from typing import Optional

class Super:
    type: str

class Foo(Super):
    type: Literal['foo']

class SuperDict(TypedDict):
    type: str

class Bar(SuperDict):
    type: Literal['bar']

class SuperTuple(NamedTuple):
    type: str

class Baz(SuperTuple):
    type: Literal['baz']

What is the actual behavior/output?

Even though Literal['bar'] is compatible with type str, as shown in the other two examples, the following error is returned.

test.py:14: error: Cannot overwrite TypedDict field "type" while extending

What is the behavior/output you expect?

PEP 589 states the following:

Additional notes on TypedDict class inheritance:

  • Changing a field type of a parent TypedDict class in a subclass is not allowed
  • Multiple inheritance does not allow conflict types for the same name field

The current behavior of TypedDict is in-line with the specification, but that restriction prevents type refinement for subtypes, a restriction that is not shared by regular classes or NamedTuple subclasses. PEP 589 does not appear to mention why that additional restriction is given to typed dicts specifically, and this restricts how well TypedDict is able to express certain structures.

Could this limitation be lifted or is there a specific reason for it to apply?

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions