Intuition: unpacking a 'tuple[int, int] | tuple[str, str]' into a new tuple should not result in 'tuple[int | str, int | str]' #5875
Replies: 1 comment 1 reply
-
Within a type checker, the types of expressions are evaluated from inside out. That is, a subexpression's type is evaluated first, and then this type information is used to inform the containing type's expression. This mirrors the order of execution at runtime. That means the type of Static type checkers do not track conditional types between two or more expressions. For example, pyright doesn't track that the narrowed type of |
Beta Was this translation helpful? Give feedback.
-
Let me preface this by saying I don't believe this behavior to be incorrect. I do think some extra precision could be had for the following situation:
The last
reveal_type
in both blocks is correct: a tuple of two unions is the tuple of those two unions--of course!The 2nd version actually surprised me at first, though. I had expected that if the type checker knows that
f
istuple[int, int] | tuple[str, str]
, then it should know that(f[0], f[1])
(or(c, a)
) is alsotuple[int, int] | tuple[str, str]
. The hindsight was "how could it if both elements areint | str
? Duh!"If it could be proven that
(f[0], f[1])
has the same type asf
while iteratingfields
, then the following shouldn't be rejected:It feels like the type checker has enough information to come to the same conclusion as my first intuition that
c < a
would be type-safe as long as each(c, a)
's type is known. But I dunno 🤷Beta Was this translation helpful? Give feedback.
All reactions