Skip to content

Narrowing unions with Literal and TypedDict #7944

Closed
@porglezomp

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

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions