Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't the type argument inferred as a union type?

This code

declare function fn<T, U>(array: T[], predicates: ((arg: T) => U)[]): [T, U];
let a = fn([1, 2, 3], [x => 2, x => 's']);

leads to this error:

The type argument for type parameter 'U' cannot be inferred from the usage. Consider specifying the type arguments explicitly. Type argument candidate 'number' is not a valid type argument because it is not a supertype of candidate 'string'. function fn(array: T[], predicates: ((arg: T) => U)[]): [T, U]

Why can't be U simply inferred to have the type string | number here?

like image 958
thorn0 Avatar asked Mar 11 '23 23:03

thorn0


1 Answers

TypeScript in general will not synthesize a union type during generic inference. The reason, in simplified terms, is that it's not desirable to do inference like this:

function compare<T>(x: T, y: T): number { ... }
// Could infer T: string | number here... but that'd be bad
compare('oops', 42);

If a generic type can't be formed by picking one of the inference candidates, you'll get the error you posted.

Experience informed this choice. In prior versions (before union types existed), {} would be inferred if no inference candidate was a supertype of all candidates. In practice this led to a lot of missed errors that looked like the example above.

like image 158
Ryan Cavanaugh Avatar answered Mar 13 '23 13:03

Ryan Cavanaugh