Skip to content

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

Closed

Description

TypeScript Version: TS@next, TS@2.7

not in TS@2.6

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.

Activity

  1. changed the title [-]Overload Regression in TS2.7[/-] [+]Overload Regression in TS2.7 -- the first hit overload is not selected[/+] on Mar 11, 2018
  2. 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[/+] on Mar 11, 2018
  3. RyanCavanaugh commented on Mar 13, 2018

    @RyanCavanaugh
    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. Anders Hejlsberg (@ahejlsberg) this is similar to one we look at last week but there's less weird inference-from-return-type in play here. Thoughts?

  4. ahejlsberg commented on Apr 2, 2018

    @ahejlsberg
    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.

    Ryan Cavanaugh (@RyanCavanaugh) There's no inference from return type in play here.

  5. added
    Working as IntendedThe behavior described is the intended behavior; this is not a bug
    and removed
    BugA bug in TypeScript
    on Apr 2, 2018
  6. locked and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions