You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
So idea: if an x is/contains a T extends Some | Union, when x is in a position where it's contextually typed by C, and C doesn't have any direct generic types
then we can narrow x using the constraint of T.
This makes us more complete, but adds surpises when you start moving code around.
Because the declaration of y doesn't provide a contextual type to x, so it just gets type T (which is un-narrowed).
Do we actually cache?
Yes! And that's the cool part, our cache key incorporates both the current reference as well as the declared type. So you can cache information about x with respect to both its declared type (T extends Union) and its declared type's constraint (Union itself).
Last time we leveraged contextual typing with CFA, we ended up with cycles. Dealt with?
getConstraintForLocation usual place, but for identifiers, property accesses, etc., getConstraintForReference.
Is there a reason why the constraint has to be a union before we consider narrowing?
Promise Truthiness Check Issues
#43071
@RyanCavanaugh took notes for this section:
let
s accesed in a callback (where we don't warn on lack of initialization)Narrowing Generic Types Constrained to Unions in Control Flow Analysis
#43183
Could imagine
x
has typeT & "a"
, but then creates huge intersections!else
case.Talked with Pyright team, they have a similar issue.
They try the declared (generic) type first, then try to get the constraint and operate on that (double-check with them).
We do something similar with
So idea: if an
x
is/contains aT extends Some | Union
, whenx
is in a position where it's contextually typed byC
, andC
doesn't have any direct generic typesx
using the constraint ofT
.This makes us more complete, but adds surpises when you start moving code around.
y
doesn't provide a contextual type tox
, so it just gets typeT
(which is un-narrowed).Do we actually cache?
x
with respect to both its declared type (T extends Union
) and its declared type's constraint (Union
itself).Last time we leveraged contextual typing with CFA, we ended up with cycles. Dealt with?
getConstraintForLocation
usual place, but for identifiers, property accesses, etc.,getConstraintForReference
.Is there a reason why the constraint has to be a union before we consider narrowing?
Narrowing Intersections of Primitives & Generics
#43131
When we have union types that sit "below" intersection types, we go wrong in our reasoning. Happens when you have generics constrained to unions.
T extends string | number
can be seen asT & (string | number)
.T & (string | number) & "hello"
, but but it's hard to normalize this after the fact.T & string & "hello" | T & number & "hello"
which would simplify toT & "hello"
.So we've modified the comparable relationship to at least just recognize this pattern, without rewriting the types at any point.
Narrowing Record Types with
in
#41478
"foo" in x
is something like a type guard that creates(typeof x) & Record<"foo", unknown>
.Record
map toany
orunknown
?unknown
so I've assumedunknown
. 😅The text was updated successfully, but these errors were encountered: