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

3.4 Regression on Type inference with union types #30694

Open
richardspence opened this issue Apr 1, 2019 · 1 comment
Open

3.4 Regression on Type inference with union types #30694

richardspence opened this issue Apr 1, 2019 · 1 comment
Assignees
Labels
Needs Investigation This issue needs a team member to investigate its status.

Comments

@richardspence
Copy link

richardspence commented Apr 1, 2019

TypeScript Version: 3.4.0-dev.201xxxxx

Search Terms: Type inference, discriminated union types

Code

type AllBoxes = ABox | BBox;

export interface ICanFindBoxes {
    findBoxes<T extends AllBoxes, K extends string>(boxName: K): T extends { type: K } ? T[] : never;
}

class Box<T extends string = string> implements ICanFindBoxes{
    type: T;
    
    public findBoxes<T extends AllBoxes, K extends string>(boxName: K): T extends { type: K } ? T[] : never {
      throw 'argg';
    }
   
}

export class ABox extends Box<'a'>{

}

export class BBox extends Box<'b'>{}

Expected behavior:
It compiles
Actual behavior:
Compile time error:

 Property 'findBoxes' in type 'Box<T>' is not assignable to the same property in base type 'ICanFindBoxes'.
  Type '<T extends AllBoxes, K extends string>(boxName: K) => T extends { type: K; } ? T[] : never' is not assignable to type '<T extends AllBoxes, K extends string>(boxName: K) => T extends { type: K; } ? T[] : never'. Two different types with this name exist, but they are unrelated.
    Type '(T extends { type: K; } ? T[] : never) | ({ type: K; } & ABox)[] | ({ type: K; } & BBox)[]' is not assignable to type 'T extends { type: K; } ? T[] : never'.
      Type '({ type: K; } & ABox)[]' is not assignable to type 'T extends { type: K; } ? T[] : never'.

11     public findBoxes<T extends AllBoxes, K extends string>(boxName: K): T extends { type: K } ? T[] : never {

The compiler is incorrectly identifying that the signatures are different when they are not. If I simplify the union type to only one it works (but this defeats the purpose of the signature).

This was working in < 3.4.1

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Apr 9, 2019
@richardspence
Copy link
Author

richardspence commented Apr 20, 2019

Interesting work around:
change the generic args to use defaults in lieu of extends
<T = AllBoxes, K extends string = never>

export interface ICanFindBoxes {
    findBoxes<T = AllBoxes, K extends string = never>(boxName: K): T extends Box<K> ? T[] : never;
}

class Box<T extends string = string> implements ICanFindBoxes{
    type: T;
    
    public findBoxes<T = AllBoxes, K extends string = never>(boxName: K): T extends Box<K> ? T[] : never {
      throw 'argg';
    }
   
}

Playground

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Needs Investigation This issue needs a team member to investigate its status.
Projects
None yet
Development

No branches or pull requests

3 participants