Open
Description
openedon Jul 28, 2017
TypeScript Version: 2.4.1
Code
Case 1
// overloaded functions
declare function f(a: number): number;
declare function f(a: string): string;
function g<T extends number | string>(a: T) {
return f(a); // either of arguments is acceptable
// ~
// Argument of type 'T' is not assignable to parameter of type 'string'.
// Type 'string | number' is not assignable to type 'string'.
// Type 'number' is not assignable to type 'string'.
}
Case 2
declare function f2<T>(a: Promise<T>): number;
declare function f2<T>(a: T): string;
function g2<T>(a: T) {
const result: string = f2(a); // first overload is ignored, but the argument can be a Promise
return result;
}
Expected behavior:
Case 1: compiles with no errors
Case 2: error that type string | number
is not assignable to type string
Actual behavior:
Case 1: error
Argument of type 'T' is not assignable to parameter of type 'string'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'
Case 2: compiles without errors
Note
I remember here were some discussions about that, so that verifying all possible paths may result in N*M complexity (N overloads, M constituent types in unions). I could not find it.
The second case seems unsafe at all, because skips a possibly valid overload which may effect on return type. I expect that f2(a)
would be of type number | string
because either of these two overloads can play. It actually has the same result with a: any
.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment