声明顺序是否会影响 TypeScript 类型推导?

Should the declaration order affect TypeScript type deduction?

似乎 TypeScript 的翻译器在某种程度上依赖于声明的顺序,至少在重载函数的情况下是这样。

假设我们有 类 用于 2 维和 3 维向量:

class Vector2 {
  public get x() : number
  public get y() : number
}
class Vector3 {
  public get x() : number
  public get y() : number
  public get z() : number
}

我们有一个重载函数,它接受 Vector2Vector3:

function add(a : Vector2, b : number) : Vector2;
function add(a : Vector3, b : number) : Vector3;

根据 add() 的哪个签名先出现 - 带有 Vector2Vector3 结果 - 编译器可能会推断出不同类型的结果,即使我们准确地作为参数传递Vector3。 例如,如果订单与上述相同,则代码如下:

const r = add(new Vector3, 5)

将returnVector2代替Vector3。 因此,如果我们将 r 的可能类型限制为 Vector3:

const r : Vector3 = add(new Vector3, 5)

代码无法编译。

这是应该的吗?因为对我来说,这看起来像是翻译器的错误。

这是 Typescript 的预期行为:当您调用重载函数时,编译器会选择 first 在调用点兼容的重载签名,而不是 最具体 签名。来自 the docs:

TypeScript chooses the first matching overload when resolving function calls. When an earlier overload is “more general” than a later one, the later one is effectively hidden and cannot be called.

因为你的 Vector3 是你的 Vector2structural subtypeVector3 重载签名更具体所以你应该在 [=11= 之前写那个] 重载签名。