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
{{ message }}
Repository navigation
Adding infer in a conditional type changes the resulting branch #22615
typeId=<T>(item: T)=>T;typeX=((t: Id)=>void)extends(t: (item: any)=>any)=>void ? "yes" : "no";// Resolves to "yes", as expectedtypeY=((t: Id)=>void)extends(t: (item: any)=> infer R)=>void ? "yes" : "no";// Resolves to "no", but "yes" is desired
The code checks whether a function that takes the identity function is assignable to a function that takes some function any => any. This is clearly assignable, and thus results in "yes". However, when replacing one any by infer R, the other branch is taken. I think that replacing any by an infer R type should never change the branch that is taken.
It is effectively a design limitation. We have the concept of instantiating a generic function type in the context of a non-generic function type (a form of unification), but we currently don't do that in conditional types. Instead, function type parameters are erased to their constraints and we infer from those. In the example above, that causes us to infer {} for the infer R type parameter. Ordinarily that would be fine because anything is assignable to {}, however in this case the type parameter occurs in a contra-variant position, so the check fails following inference. This isn't specific to conditional types, a similar thing can happen during regular type inference in function calls.
The proper fix for this would be have type inference perform instantiation of a source type in the context of a target type when the source type is a generic function type.
Activity
RyanCavanaugh commentedon Mar 16, 2018
Anders Hejlsberg (@ahejlsberg) bug indeed?
ahejlsberg commentedon Mar 21, 2018
It is effectively a design limitation. We have the concept of instantiating a generic function type in the context of a non-generic function type (a form of unification), but we currently don't do that in conditional types. Instead, function type parameters are erased to their constraints and we infer from those. In the example above, that causes us to infer
{}for theinfer Rtype parameter. Ordinarily that would be fine because anything is assignable to{}, however in this case the type parameter occurs in a contra-variant position, so the check fails following inference. This isn't specific to conditional types, a similar thing can happen during regular type inference in function calls.The proper fix for this would be have type inference perform instantiation of a source type in the context of a target type when the source type is a generic function type.