Skip to content
大纲

类型性质

类型推论

类型推论即类型是在何处被推断的

  • 变量和成员在初始化值时,将根据值的类型设置对应的类型
  • 若值为数组,则会推断数组元素类型为初始化值的元素类型的联合类型
  • 在有上下文的情况下,参数类型可以被自动推断,指定参数类型将忽略上下文推断

示例

ts
// 根据初始值设置类型
let str = "777"; //let str: string
// str = 777 //Error

// 对数组元素设置联合类型
let arr = [false, null]; //let arr: (boolean | null)[]
arr = [null, null, true];
// arr = [1] //Error

// 根据上下文,这里指定了 `arr` 元素的类型为 `number` ,所以 `cur` 参数被推断为 `number` 类型
function getSum(arr: number[]) {
  return arr.reduce((sum, cur) => (sum += cur), 0);
}

类型断言

类型断言即告诉编辑器某变量或成员在当前上下文的具体类型

  • 使用 <Type>variable 的格式指定变量的类型
  • 使用 variable as Type 的格式指定变量的类型
  • 在 JSX 中只允许使用 as 进行断言
  • 如果某变量或成员非 null ,可以使用 variable! 的格式进行说明

类型保护

类型保护即告诉编译器某变量或成员在给定的上下文中的具体类型,使用类型保护可以避免重复的类型断言

  • 使用 === 运算符或 || 运算符对成员进行 null 类型保护,其用法同 js
  • 使用 typeof 类型保护确保基本类型成员的类型,其用法同 js
  • 使用 instanceof 类型保护确保实例类型成员的类型,其用法同 js
  • 使用自定义类型保护确保成员的具体类型
    • 自定义类型保护需要声明一个函数,其返回值是布尔类型,但使用类型谓词进行描述
    • 类型谓词描述的格式为 parameterName is TypeparameterName 为函数中的某个参数
ts
class Rect {
  width: number;
  height: number;
  area: number;
}

const isRect = (obj: any): obj is Rect =>
  typeof obj === "object" &&
  typeof obj.width === "number" &&
  typeof obj.height === "number";

const unkonw = {};
if (isRect(unkonw)) {
  console.log(unkonw.area);
}

可辨识联合

可辨识联合又叫 标签联合 或 代数数据联合,即对于多个单例类型的联合,可以通过可辨识的属性实现该属性上的类型保护,需要具有以下三个要素:

  • 具有普通的单例类型属性 (可辨识的特征)
  • 一个类型别名包含了那些类型的联合 (联合)
  • 此属性上的类型保护

示例

ts
interface A {
  name: "a";
  a: string;
}
interface B {
  name: "b";
  b: number;
}
type AB = A | B;

function test(arg: AB) {
  switch (arg.name) {
    case "a":
      return "a";
    case "b":
      return "b";
    default:
      return "";
  }
}

类型兼容性

结构类型与名义类型

  • 结构类型: 只使用其成员来描述类型的方式
  • 名义类型: 通过明确的声明或类型的名称决定类型的方式

类型兼容性

  • ts 中的类型兼容性基于结构子类型
  • 使用该方式只检测类型的组成结构而非名称

兼容性规则

  • 基本规则:若 X 兼容 Y ,则 Y 至少具有与 X 相同的属性
  • 比较函数
    • 比较的是参数列表
  • 比较枚举类型
    • 数字枚举类型与数字类型相互兼容
    • 不同枚举类型之间互不兼容
  • 比较类类型
    • 只比较实例成员,不比较静态恒源和构造函数
    • 若目标类型含有私有成员,则源类型必须含有来自同一个类的该私有成员
  • 比较泛型接口
    • 未指定泛型类型的泛型参数时,会将泛型参数当做 any 处理后进行比较
    • 指定泛型类型的泛型参数时,沪江泛型参数转换为具体的类型后进行比较