英文:
Typescript can't correctly infer type of parameter inside function overload
问题
代码部分已被排除,以下是翻译好的内容:
"调用函数foo时,正确的类型受到强制,但在函数内部,我希望在if语句内,TypeScript 能正确地推断当name等于'a'时age是一个字符串。是否有其他方法可以实现这一点?"
function foo(name: "a", age: string): void;
function foo(name: "b", age: number): void;
function foo(name: "a" | "b", age: string | number) {
if (name === "a") {
const x = age; // 期望x是字符串,但实际上是字符串 | 数字;
}
}
foo("a", "asd"); // 正确
foo("a", 5); // 错误
foo("b", 5); // 正确
foo("b", "asd"); // 错误
英文:
When calling function foo the correct types are enforced but inside the function i would expect that inside the if statement typescript would correctly infer that age is a string when name equals "a". Is there another way to do this?
function foo(name: "a", age: string): void;
function foo(name: "b", age: number): void;
function foo(name: "a" | "b", age: string | number) {
if (name === "a") {
const x = age; // Would expect x to be string but is string | number;
}
}
foo("a", "asd"); // Correct
foo("a", 5); // Error
foo("b", 5); // Correct
foo("b", "asd"); // Error
答案1
得分: 2
I run into this problem all the time and it is why I try to avoid function overloads in TypeScript. This isn't really how they work, since there is just one implementation the TS compiler doesn't discriminate the function arguments. I imagine this has to do with backwards-compatibility but it sure is a pain.
The only workaround I have found is explicitly using discriminated unions in the function signature--but this requires defining the arguments as spread.
function foo(...[name, age]: [name: "a", age: string] | [name: "b", age: number]) {
if (name === "a") {
const x = age;
// ^? const x: string
}
if (name === "b") {
const x = age;
// ^? const x: number
}
}
I don't know of any issue on the TypeScript GitHub that addresses this but there may be one.
英文:
I run into this problem all the time and it is why I try to avoid function overloads in TypeScript. This isn't really how they work, since there is just one implementation the TS compiler doesn't discriminate the function arguments. I imagine this has to do with backwards-compatibility but it sure is a pain.
The only workaround I have found is explicitly using discriminated unions in the function signature--but this requires defining the arguments as spread.
function foo(...[name, age]: [name: "a", age: string] | [name: "b", age: number]) {
if (name === "a") {
const x = age;
// ^? const x: string
}
if (name === "b") {
const x = age;
// ^? const x: number
}
}
I don't know of any issue on the TypeScript GitHub that addresses this but there may be one.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论