Skip to content

类型兼容性(compatible)

在 TypeScript 中,类型兼容性(Compatibility)规则决定了一个类型是否可以被赋值给另一个类型。这是静态类型检查的核心部分,帮助确保类型安全。TypeScript 的兼容性原则广泛但遵循一些基本原则,旨在保持灵活性的同时确保类型的一致性和安全性。以下是一些关键点:

1. 结构兼容性原则

TypeScript 采用的是“结构兼容性”,而不是“名义兼容性”(即基于名称的兼容)。这意味着,如果两个类型的结构兼容,即使它们的名称不同,也可以相互赋值。结构兼容性主要关注类型的形状(即它们的属性和方法)是否匹配,而不是它们的名字。

2. 属性兼容性

如果源类型(被赋值的类型)的每个属性都是目标类型(赋值目标的类型)相应属性的子类型,那么它们在属性方面是兼容的。例如,如果目标类型有一个可选属性,源类型可以不包含这个属性;如果目标属性是非只读的,源属性可以是只读的。

3. 函数兼容性

  • 参数兼容性:目标函数的每个参数都必须与源函数的对应参数兼容(源参数可以是目标参数的子类型)。
  • 返回类型兼容性:源函数的返回类型必须是目标函数返回类型的子类型。
  • 可选参数和默认参数:源函数可以少于目标函数的参数,但不能多。源函数的额外参数必须是可选的。
  • 参数个数:如果目标函数使用了剩余参数(...args),源函数可以传递任意数量的参数。

4. 类的兼容性

  • 源类需要实现目标接口的所有必需成员。
  • 源类的成员可以是目标类对应成员的子类型。
  • 构造函数不参与兼容性检查,但实例成员和静态成员都要检查。

5. 联合类型与交叉类型的兼容性

  • 一个类型可以赋值给联合类型,只要它能赋值给联合中的任何一个类型。
  • 一个类型可以赋值给交叉类型,它必须满足交叉类型中所有类型的约束。

6. 类型擦除与 any、unknown、never

  • any 类型可以赋值给任何类型,任何类型也可以赋值给 any,这使得它成为类型系统中最宽松的类型。
  • unknown 类型类似于 any,但更安全,它只能被明确地类型断言或通过类型守卫赋值给其他类型。
  • never 类型与其他任何类型都不兼容,也没有类型可以赋值给 never。

了解和掌握这些兼容性原则,对于编写健壮的 TypeScript 代码至关重要,它帮助开发者在享受静态类型检查带来的好处的同时,保持代码的灵活性。

Released under the MIT License.