Skip to content

Narrowing unions with Literal and TypedDict #7944

Description

@porglezomp

I expected the following code to narrow the type of the argument, but it is unable to.

from mypy_extensions import TypedDict
from typing_extensions import Literal

TaggedStr = TypedDict('TaggedStr', {'tag': Literal['str'], 's': str})
TaggedInt = TypedDict('TaggedInt', {'tag': Literal['int'], 'i': int})

def do_tagged(x: Union[TaggedStr, TaggedInt]):
    if x['tag'] == 'str':
        reveal_type(x)
    else:
        reveal_type(x)
  • What is the actual behavior/output?
    No narrowing occurs:
example.py:10: note: Revealed type is 'Union[TypedDict('example.TaggedStr', {'tag': Literal['str'], 's': builtins.str}), TypedDict('example.TaggedInt', {'tag': Literal['int'], 'i': builtins.int})]'
example.py:12: note: Revealed type is 'Union[TypedDict('example.TaggedStr', {'tag': Literal['str'], 's': builtins.str}), TypedDict('example.TaggedInt', {'tag': Literal['int'], 'i': builtins.int})]'
  • What is the behavior/output you expect?
    I'd expect the comparisons against literal keys to allow narrowing the types.
example.py:10: note: Revealed type is 'TypedDict('example.TaggedStr', {'tag': Literal['str'], 's': builtins.str})'
example.py:12: note: Revealed type is 'TypedDict('example.TaggedInt', {'tag': Literal['int'], 'i': builtins.int})'
  • What are the versions of mypy and Python you are using?
    mypy 0.740, Python 3.7.4

Activity

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions