Typescript无法正确推断函数重载内部参数的类型。

huangapple go评论61阅读模式
英文:

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
  }
}

TypeScript Playground link

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
  }
}

TypeScript Playground link

I don't know of any issue on the TypeScript GitHub that addresses this but there may be one.

huangapple
  • 本文由 发表于 2023年3月9日 23:38:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75686835.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定