Consider this code snippet for illustration:
function foo(t: "number"): number
function foo(t: "string"): string
function foo(t: "boolean"): boolean
function foo(t: "number" | "string" | "boolean"): number | string | boolean {
if (Math.random() < 0.5) {
if (t === "number") {
return 1;
} else if (t === "boolean") {
return true;
} else {
return "1";
}
} else {
return foo(t);
}
}
The error message is as follows:
No overload matches this call.
Overload 1 of 3, '(t: "number"): number', gave the following error.
Argument of type '"string" | "number" | "boolean"' is not assignable to parameter of type '"number"'.
Type '"string"' is not assignable to type '"number"'.
Overload 2 of 3, '(t: "string"): string', gave the following error.
Argument of type '"string" | "number" | "boolean"' is not assignable to parameter of type '"string"'.
Type '"number"' is not assignable to type '"string"'.
Overload 3 of 3, '(t: "boolean"): boolean', gave the following error.
Argument of type '"string" | "number" | "boolean"' is not assignable to parameter of type '"boolean"'.
Type '"string"' is not assignable to type '"boolean"'.(2769)
On the other hand, TypeScript successfully checks the following code:
function bar(t: "number"): number
function bar(t: "string"): string
function bar(t: "boolean"): boolean
function bar(t: "number" | "string" | "boolean"): number | string | boolean {
if (Math.random() < 0.5) {
if (t === "number") {
return 1;
} else if (t === "boolean") {
return true;
} else {
return "1";
}
} else {
switch (t) {
case "number": return bar(t);
case "string": return bar(t);
case "boolean": return bar(t);
}
}
}
Refer to TypeScript Playground.
I am curious why TypeScript disapproves of transitive type inference in the initial code snippet. Any insights on this matter would be greatly appreciated. Thank you.