使用 returns 与其参数类型相同的可区分联合来声明 TypeScript 函数的最佳方法是什么?

What's the best way to declare a TypeScript function with a discriminated union that returns the same type as its parameter?

给定这个简化的 vanilla JS 函数:

function getStringOrNumber(val) {
  if (typeof val === 'string') {
      return 'It was a string';
  } else {
      return 5;
  }
}

我如何告诉 TypeScript 当它得到一个字符串时它 returns 一个字符串,当它得到一个数字时它 returns 一个数字?

我尝试了不同的方法,发现使用这些重载是有效的,但它似乎过于复杂,我想知道我是否遗漏了什么。特别是,在此解决方案中,我不明白为什么需要第三行(有关详细信息,请参阅下面的 link)。

function useOverloadsExtra(val: string): string
function useOverloadsExtra(val: number): number
function useOverloadsExtra(val: string | number): string | number
function useOverloadsExtra(val: string | number): string | number {
    if (typeof val === 'string') {
        return 'It was a string';
    } else {
        return 5;
    }
}

Here are the other solutions I tried

您的重载解决方案已经完成。问题出在你的测试上。在您的测试中,您正在调用将联合作为参数传递的方法,但联合不是允许的值:只有 stringnumber 是。最后重载("implementation overload")is not part of the signature。所以你的测试必须执行缩小,像这样:

function getValOverloads(val: string | number): string | number {
    if (typeof val === 'string')
        return useOverloads(val);
    else
        return useOverloads(val);
}

如果您希望能够传递联合(并因此接收联合作为 return 值),您应该添加第三个重载(就像您在 useOverloadsExtra 上所做的那样)。