Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overload Regression in TS2.7 -- the first matching overload is not selected #22471

Closed
HerringtonDarkholme opened this issue Mar 11, 2018 · 2 comments
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented Mar 11, 2018

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 vuejs/vue#7640. The code used to compile in TS 2.6.

@HerringtonDarkholme HerringtonDarkholme changed the title Overload Regression in TS2.7 Overload Regression in TS2.7 -- the first hit overload is not selected Mar 11, 2018
@HerringtonDarkholme HerringtonDarkholme changed the title Overload Regression in TS2.7 -- the first hit overload is not selected Overload Regression in TS2.7 -- the first matching overload is not selected Mar 11, 2018
@RyanCavanaugh
Copy link
Member

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?

@mhegazy mhegazy added the Bug A bug in TypeScript label Mar 29, 2018
@mhegazy mhegazy added this to the TypeScript 2.9 milestone Mar 29, 2018
@ahejlsberg
Copy link
Member

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.

@ahejlsberg ahejlsberg added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Bug A bug in TypeScript labels Apr 2, 2018
@mhegazy mhegazy closed this as completed Apr 26, 2018
@microsoft microsoft locked and limited conversation to collaborators Jul 31, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants