Closed
Description
Bug Report
Mypy has a feature where a union of TypedDicts can be narrowed down based on the value of entries: https://mypy.readthedocs.io/en/stable/literal_types.html#tagged-unions
But this doesn't seem to work with pattern matching.
To Reproduce
from typing import Literal, TypedDict
class A(TypedDict):
tag: Literal["a"]
name: str
class B(TypedDict):
tag: Literal["b"]
num: int
def f(d: A | B) -> None:
if d["tag"] == "a":
print(d["name"])
elif d["tag"] == "b":
print(d["num"])
def g(d: A | B) -> None:
match d["tag"]:
case "a":
print(d["name"]) # E: TypedDict "B" has no key "name"
case "b":
print(d["num"]) # E: TypedDict "A" has no key "num"
https://mypy-play.net/?mypy=latest&python=3.11&gist=22cd1c2a185a5182b98e12c1e5dd33e2
Expected Behavior
The narrowing in function g
should work the same as in function f
.
Actual Behavior
main.py:20: error: TypedDict "B" has no key "name" [typeddict-item]
main.py:22: error: TypedDict "A" has no key "num" [typeddict-item]
Found 2 errors in 1 file (checked 1 source file)
The dictionaries are not correctly narrowed in the match branches.
Your Environment
See mypy-play link above.