microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.73k stars 12.45k forks source link

Generic type inference failure in a union. #29471

Open bowenni opened 5 years ago

bowenni commented 5 years ago

TypeScript Version: 3.3.0-dev.20190117

Search Terms: generic type inference, union types

Code

function f1<A1, B1>(cb: (a: A1, b: B1) => void) {
  f2(cb);  // I expect no errors
}

function f2<A2, B2>(cb: ((x: number, a: A2, b: B2) => void)|
                    ((a: A2, b: B2) => void)) {}  // If I swap the two types it compiles

Expected behavior: No errors.

Actual behavior:

TS2345: Argument of type '(a: A1, b: B1) => void' is not assignable to parameter of type '((x: number, a: B1, b: B1) => void) | ((a: B1, b: B1) => void)'.
  Type '(a: A1, b: B1) => void' is not assignable to type '(x: number, a: B1, b: B1) => void'.
    Types of parameters 'a' and 'x' are incompatible.
      Type 'number' is not assignable to type 'A1'.

Playground Link: http://www.typescriptlang.org/play/#src=function%20f1%3CA1%2C%20B1%3E(cb%3A%20(a%3A%20A1%2C%20b%3A%20B1)%20%3D%3E%20void)%20%7B%0D%0A%20%20f2(cb)%3B%0D%0A%7D%0D%0A%0D%0Afunction%20f2%3CA2%2C%20B2%3E(cb%3A%20((x%3A%20number%2C%20a%3A%20A2%2C%20b%3A%20B2)%20%3D%3E%20void)%7C%0D%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20((a%3A%20A2%2C%20b%3A%20B2)%20%3D%3E%20void))%20%7B%7D

Related Issues: I looked around and didn't anything obviously related.

weswigham commented 5 years ago

Hm. If anything, the order of the union members shouldn't change the behavior.