Type inferences with overloads have failed #10645
Copy link
Copy link
Closed
Labels
BugA bug in TypeScriptA bug in TypeScriptSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specificationWorking as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
Milestone
Description
TypeScript Version: master
Code
function f<a, b>(g: (a: a) => b, a: a): b {
return g(a);
}
var g = <{(data: number): number; (data: string): string;}>((p: number) => p);
f(g, ''); // string
f(g, 0); // error, should return numberExpected behavior:
$ node built/local/tsc.js --noEmit --lib es6 --strictNullChecks --noImplicitAny index.ts
Actual behavior:
$ node built/local/tsc.js --noEmit --lib es6 --strictNullChecks --noImplicitAny index.ts
index.ts(6,1): error TS2453: The type argument for type parameter 'a' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugA bug in TypeScriptA bug in TypeScriptSpecIssues related to the TypeScript language specificationIssues related to the TypeScript language specificationWorking as IntendedThe behavior described is the intended behavior; this is not a bugThe behavior described is the intended behavior; this is not a bug
Activity
mhegazy commentedon Aug 31, 2016
Nathan Shively-Sanders (@sandersn) can you take a look
falsandtru commentedon Oct 1, 2016
any updates?
sandersn commentedon Oct 3, 2016
No, I haven't had a chance to look at this yet.
sandersn commentedon Oct 13, 2016
This is, unfortunately, how TypeScript is intended to treat overloads during type inference. Type inference is not smart enough to infer an overloaded call signature, so it just chooses the last one. If you reverse the order of declarations, you will see that the error switches to the other call.
Adapted from the spec, section 3.10.6 (Type Inference):
In the example code, S is
{ (data: number): number; (data: string) => string }and T is{ (a: a) => b }. That means that type inference always returnsa=string, b = string.falsandtru commentedon Oct 13, 2016
I see, thx!