TypeScript Version: TS@next, [email protected]
not in [email protected]
Search Terms: overload / overloading
Code
type Prop<T> = { (): T }
declare function test<T>(a: Prop<T>): T
declare function test(a: Prop<any>): {} // toggle this line
var a = test(Array)
a.push
Expected behavior:
Code compiles. Since the first overloading should always match.
Actual behavior:
Code doesn't compile. TSC chooses the second overloading instead of the first one.
Toggling off the second overload signature can make code compile but should not.
Note: changing Array to String belies the problem.
Playground Link:
http://www.typescriptlang.org/play/#src=type%20Prop%3CT%3E%20%3D%20%7B%20()%3A%20T%20%7D%0A%0Adeclare%20function%20test%3CT%3E(a%3A%20Prop%3CT%3E)%3A%20T%0Adeclare%20function%20test(a%3A%20Prop%3Cany%3E)%3A%20%7B%7D%20%2F%2F%20toggle%20this%20line%0A%0Avar%20a%20%3D%20test(Array)%0A%0Aa.push
Related Issues:
More info:
This is a reduced version of https://github.com/vuejs/vue/issues/7640. The code used to compile in TS 2.6.
Reduced further (thanks for getting it so small to begin with!):
type Prop<T> = { (): T }
declare function test<T>(a: Prop<T>): T;
declare function test(a: Prop<any>): {};
declare function fn(): any[];
declare function fn<T>(item?: T): T[];
var a = test(fn);
// Check inferred type of above without introducing contextual return type
var a: any[];
Confirmed broken between 2.6 and 2.7. @ahejlsberg this is similar to one we look at last week but there's less weird inference-from-return-type in play here. Thoughts?
This is caused by #19424 which indeed was a breaking change. We are now more precise when inferring from generic signatures in the sense that we erase type parameters to their constraints instead of blindly erasing them to any. In both of the examples above we're inferring from generic signatures (because the last, and therefore supposedly most general, signatures in Array and fn are generic), and in both cases we end up erasing the signature type parameter to {} instead of any.
@RyanCavanaugh There's no inference from return type in play here.