TypeScript:使用对象参数和 IntelliSense 重载 functions/methods

TypeScript: Overloaded functions/methods with object argument and IntelliSense

我试过像这样重载函数 f(当然只是一个例子):

function f(params: {x: number, y: number}): number;
function f(params: {x: number, z: number}): number;
function f(params: {x: number, y: number} | {x: number, z: number}): number {
  if ('y' in params) return params.x + params.y;
  if ('z' in params) return params.x * params.z;
}

这已经引起了问题,因为编译器给我 “Function lacks ending return statement and return type does not include 'undefined'.ts(2366)”。这很奇怪,因为始终必须满足实施中的两个 if 条件之一。

但我来这里是为了一些不同的事情(然而,这可能是相关的):当我想调用 f 并因此写一些类似 f({y: 4, 的东西然后按 Ctrl+Shift+Space 来激活 IntelliSense(在 VSCode 1.58.2 中),它对缺少的属性提出了两个建议(见图):x,这是正确的,而且 z,这装不下了。

我希望一旦我输入 yparams 的类型就会缩小到 {x: number, y: number},但这似乎并没有发生。为什么会这样,我可以做些什么来改变它吗?

你的两个问题都取决于 Typescript 中的联合类型不排他。您可以找到关于此主题的多个讨论:

XOR in union allows both

Proposal: Add an "exclusive or" (^) operator

虽然这种行为可能看起来令人困惑(在某种程度上对我来说仍然如此),但它解释了:

  1. 为什么你的两个 if 条件没有被 Typescript 编译器认为是详尽无遗的:事实上,你仍然可能遇到 params 的情况 xz

  2. 为什么 Intellisense 将 xyz 显示为 params 的可能属性:事实上,这被认为是有效的赋值来自 TS:

const a: { x: number, y: number } | { x: number, z: number } = { x: 1, y: 2, z: 3}