Skip to content

Narrowing Union[TypedDict] with in keyword #11080

Closed
@devin-git

Description

@devin-git

Feature

mypy should narrow Union[TypedDict] when using in keyword.

Pitch

from typing import Literal, TypedDict, Union

Key = Literal['a', 'b']

class A(TypedDict):
    a: int
    
class B(TypedDict):
    b: int

def try_print(x: Union[A, B], key: Key):
    if key in x:
        print(x[key])

The example above triggers errors in mypy:

main.py:13: error: TypedDict "A" has no key "b"
main.py:13: error: TypedDict "B" has no key "a"

In theory, if key in x condition should provide enough information for mypy to narrow the type of parameter x. It should know that x is aligned with key, so the print statement is type safe.

Current workaround is to manually cast the type as below,

    if key == 'a':
        print(cast(A, x)[key])
    else:
        print(cast(B, x)[key])

but when there's much more keys and TypedDicts involved, this approach would become verbose and messy.

If mypy can add this narrowing feature, it will allow more flexibility for TypedDict Union use cases

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions