原因是您有一个 数组联合,这会导致您观察到的问题。
让我们通过命名类型让代码更清晰一些。以后再讨论会容易很多:
type A = { version: number, a: string };
type B = { version: number, b: string };
所以,你拥有的是list: (A[] | B[]),而不是(A | B)[]。两者具有不同的语义 - 后者确实意味着您可以在单个数组中混合 A 和 B 类型,而您只允许一个数组。但是,在打字方面有所不同。
TypeScript 确实 承认您拥有的联合的所有成员都是数组,因此list.sort() 是一个现有方法。实际上,它是两种方法——一种来自A[],另一种来自B[]。但是,为了确保类型安全,TypeScript 将合并两个 .sort() 方法的签名。
签名期望这些回调被传入:
type sortA = (x: A, y: A) => number;
type sortB = (x: B, y: B) => number;
所以,为了合并两者,TypeScript 将使用
type mergedSort = sortA & sortB
这会导致问题 - 实现 mergedSort 的函数必须接受 As 或 Bs 但不能同时接受两者。唯一可能的函数将接受any 类型,因为它满足限制。
因此,为什么你会得到 any 的推断类型 - 它是唯一可以与任一数组一起使用的类型。
相比之下,如果您有(A | B)[],那么.sort() 方法的回调将如下所示:
type sortMixed = (x: A | B, y: A | B): number;
由于联合中的类型共享一个version 属性,因此使用它是有效的:
type A = { version: number, a: string };
type B = { version: number, b: string };
const list: (A | B)[] = [];
list.sort((a, b) => {
return a.version - b.version;
});
Playground Link