Skip to content

Unexpected type argument inference #46623

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

Closed
ltblue opened this issue Nov 1, 2021 · 3 comments
Closed

Unexpected type argument inference #46623

ltblue opened this issue Nov 1, 2021 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@ltblue
Copy link

ltblue commented Nov 1, 2021

Bug Report

πŸ”Ž Search Terms

generic type argument inference

πŸ•— Version & Regression Information

4.4.4

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

type Type<T extends 1|2> = 
  T extends 1 ? number : 
  T extends 2 ? string :
  never;

type Foo<T extends 1|2> = (x: {a: T, b: Type<T>}) => void;

function foo1(x: {a: 1, b: number} | {a: 2, b: string}) {}
function foo2(x: {a: 2, b: string} | {a: 1, b: number}) {}

function bar<T extends 1|2> (a: T, b: Foo<T>) {}

bar(1, foo1); // ok
bar(2, foo1); // error: Argument of type '2' is not assignable to parameter of type '1'.(2345)

bar(1, foo2); // error: Argument of type '1' is not assignable to parameter of type '2'.(2345)
bar(2, foo2); // ok

πŸ™ Actual behavior

In bar, foo1 is always inferred to be Foo<1> and foo2 is always inferred to be Foo<2>

πŸ™‚ Expected behavior

It is supposed to be no error there because foo1 and foo2 have the same type, which can satisfy all the four calls.

@andrewbranch
Copy link
Member

Duplicate of #45603, already fixed in nightly

@andrewbranch andrewbranch added the Duplicate An existing issue was already created label Nov 1, 2021
@ltblue
Copy link
Author

ltblue commented Nov 2, 2021

Duplicate of #45603, already fixed in nightly

Thanks. But I found it doesn't work if I use function overload instead of union type in nightly. Here is the code.

type Type<T extends 1|2> = 
  T extends 1 ? number : 
  T extends 2 ? string :
  never;

type Foo<T extends 1|2> = (x: {a: T, b: Type<T>}) => void;

function foo1(x: {a: 1, b: number}): void;
function foo1(x: {a: 2, b: string}): void;
function foo1(x: any) {}

function bar<T extends 1|2> (a: T, b: Foo<T>) {}

bar(1, foo1); // error: Argument of type '1' is not assignable to parameter of type '2'.(2345)
bar(2, foo1); // ok

Playground v4.5.0-dev.20211101

@andrewbranch
Copy link
Member

That's expected; inference doesn't pick overloads; it just uses the last one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

2 participants