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
Technically this is conservative. Won't work for [number, number] | [string, string].
Internals get gnarly. Have to funnel around more information about the minimum argument count that might be passed in.
Ideally we could try out multiple signatures. However, architecturally TypeScript assumes it can assign types for symbols once and never again, and this is a large boulder to move. It's been a long-standing problem in the compiler. But also, doing so could cause us to do a lot of work.
Stack of PRs before that's reasonable for us to do.
[[Meta: What's the canonical issue for this?]]
Covariance breaks when checking for undefined in a type
Makes things slower too because we can't trust variance measurements...
Falling back to structural checking is very very slow.
We also have anecdotally seen types that rely on the fact that TypeScript uses the identity relationship to compare conditional types in this way.
Had a PR from @Andarist which introduced new variance measurement types which saved some work - basically signaled "unmeasurable" but require the identity relationship.
Basically in the example, variance of T in Setter is marked as a special type of unmeasurable. Instances of Setter would be compared in an invariant manner; however, any variance checks for type parameters that are fed into Setter (i.e. U) are marked as unmeasurable.
Still might end up in structural checks anyway.
Feels like at that point, might as well just mark as unmeasurable.
Just had to do a revert of correctly marking types as Unreliable, but not of Unmeasurable.
We need Better Variance™️?
It's not great, but maybe it's okay to be more conservative?
Not just a matter of being more conservative. In our type system, conditional types can make choice; but they may make choices based on incorrect variance checks.
Can defeat this with an Evaluate alias.
If we had a better way to do structural checking more efficiently, that would allow us to fix these issues up.
Conclusion:
We don't know!
We want a running list of places where variance is measured incorrectly.
Allowing Calls Ending with Unions
#55185
a: number, b: number, c?: numberinstead of two signatures.[number, number] | [string, number]becomes[number, string | number].[number, number] | [string, string].Covariance breaks when checking for
undefinedin a type#55161
Ts inFoo extends T ? A : Bto figure out variance here.type Setter<T> = undefined extends T ? () => undefined : {};, we decide thatTis invariant.Uis invariant intype Test<U> = { 0: Setter<U> };which is undesirable. Direct structural instantiation will often permit types.Tas unmeasurable (Mark conditional extends as Unmeasurable and use a conditional-opaque wildcard for type erasure #43887)TinSetteris marked as a special type of unmeasurable. Instances ofSetterwould be compared in an invariant manner; however, any variance checks for type parameters that are fed intoSetter(i.e.U) are marked as unmeasurable.Unreliable, but not ofUnmeasurable.Evaluatealias.