microsoft / TypeScript

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

QuickInfo misleading with signatures from higher order function type inference #30373

Open ajafff opened 5 years ago

ajafff commented 5 years ago

TypeScript Version: 3.4.0-dev.20190313

Search Terms:

Code

interface T1 {}

declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
declare function list<T extends T1>(a: T): T[];
declare function box<T extends T1>(x: T): { value: T };

const listBox = pipe2(list, box);

Expected behavior:

Propagated type parameters should be renamed if a different type with the same name is used in the constraint or initializer of any other propagated type parameter.

For example: <T extends T1, T2 extends T1>.

Actual behavior:

Hovering over listBox displays const listBox: <T extends T1, T1 extends T1>(a: [T, T1]) => [T[], {value: T1;}]

Note the T1 extends T1 and T extends T1 where T1 refers to something completely different.

This is not limited to renamed type parameters. Hovering over listBox in the following code displays circular type parameter constraints (<T extends V, V extends T>) without any renaming going on:

interface T {}
interface V {}

declare function pipe2<A, B, C, D>(ab: (a: A) => B, cd: (c: C) => D): (a: [A, C]) => [B, D];
declare function list<T extends V>(a: T): T[];
declare function box<V extends T>(x: V): { value: V };

const listBox = pipe2(list, box);
ajafff commented 5 years ago

This issue is actually not limited to type display in quick info. The generated declaration file (when exporting listBox) also contains these invalid references and therefore causes type errors for consumers.

This looks related to #31605. Maybe it's fixed by #31544