Skip to content

Narrowing Union[TypedDict] with in keyword #11080

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

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions