Skip to content

Support inferring dict literals to be a union of TypedDicts #13274

Closed
@RobertCraigie

Description

@RobertCraigie

Feature

from __future__ import annotations
from typing import TypedDict

class A(TypedDict, total=False):
    name: str

class B(TypedDict, total=False):
    name: str

def foo(data: A | B) -> None:
    ...

# this should not report an error
foo({"name": "Robert"})  # error: Type of TypedDict is ambiguous, could be any of ("A", "B")

Pitch

While the code example provided is nonsensical, I ran into this error using real world types. In the more abstract sense, inferring the {"name": "foo"} expression to be A | B should be supported as it is type safe. On top of that, Pyright also supports this pattern and infers the expression correctly.

There is also a "bug" with the check in that it doesn't respect nested types, consider this case:

from __future__ import annotations
from typing import TypedDict

class A(TypedDict, total=False):
    foo: C

class B(TypedDict, total=False):
    foo: D

class C(TypedDict, total=False):
    c: str

class D(TypedDict, total=False):
    d: str

def foo(data: A | B) -> None:
    ...

foo({"foo": {"c": "foo"}})  # error: Type of TypedDict is ambiguous, could be any of ("A", "B")

In this case, there is no ambiguity, the expression can be safely inferred to be of type A.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions