Skip to content

in keyword should narrow Union[TypedDict, ...] #9953

Open
@mashumafi

Description

@mashumafi

Feature

Using in on a Union[TypedDict] should narrow the Union. There is already something similar for isinstance that can narrow based on types. If a certain key exists you could narrow down that your types from a Union as well. This would prevent an error saying a certain key is missing because you checked already, they code can safely access the key. Currently the only workaround for this would be to use cast() but really shouldn't be necessary.

Pitch

After the change the following code should pass validation.

from typing import castm Union
from typing_extensions import TypedDict

class Movie(TypedDict):
    name: str
    year: int

class MovieResponse(TypedDict):
    movie: Movie

class Book(TypedDict):
    name: str
    year: int

class BookResponse(TypedDict):
    book: Book

MediaResponse = Union[MovieResponse, BookResponse]

response : MediaResponse = MovieResponse(movie=Movie(name="Blade Runner", year=1982))

if 'movie' in response:
    reveal_type(response)  # Current: Union[MovieResponse, BookResponse]
                           # Desired: Union[MovieResponse]
    print(response["movie"])  # This fails due to `BookResponse` not having a key "movie"
                              # but we already validated existance of the 'movie' key and that type
                              # should no longer be considered here
    print(cast(MovieResponse, response)["movie"])  # current workaround

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions