返回

TypeScript 4.4 发布,探秘更新亮点,让开发更便捷

前端

TypeScript 4.4 发布 - 特性中文介绍

全新的流程控制类型推断

TypeScript 4.4 在流程控制语句中引入了新的类型推断规则,简化了代码并提高了代码安全性。

  • Aliased Conditions:使用类型别名来简化条件判断。例如,你可以定义一个类型别名 IsAdmin 来表示用户是否是管理员,然后在条件判断中使用它,如下所示:
type IsAdmin = boolean;

function isAdmin(user: User): IsAdmin {
  return user.role === "admin";
}

if (isAdmin(currentUser)) {
  // do something for admins
}
  • Discriminants:在联合类型中使用判别属性来改进类型推断。例如,你可以定义一个联合类型 Shape 来表示不同的形状,每个形状都有一个 type 属性来表示形状的类型,如下所示:
interface Shape {
  type: "circle" | "square" | "triangle";
}

function getArea(shape: Shape): number {
  switch (shape.type) {
    case "circle":
      return Math.PI * shape.radius ** 2;
    case "square":
      return shape.sideLength ** 2;
    case "triangle":
      return 0.5 * shape.base * shape.height;
  }
}

新增 Template Literal Types

TypeScript 4.4 中新增了 Template Literal Types,允许你创建更具表达力的类型。

  • 使用 Template Literal Types,你可以创建具有动态长度的元组类型。例如,你可以定义一个类型 TupleOfNumbers 来表示一个数字元组,如下所示:
type TupleOfNumbers = [number, ...number[]];

function sum(numbers: TupleOfNumbers): number {
  return numbers.reduce((a, b) => a + b, 0);
}
  • Template Literal Types 还可以用于创建具有动态键的联合类型。例如,你可以定义一个类型 RecordOfStrings 来表示一个字符串记录,如下所示:
type RecordOfStrings = {
  [key: string]: string;
};

function printKeys(obj: RecordOfStrings): void {
  console.log(Object.keys(obj));
}

导出声明的类型推断增强

TypeScript 4.4 增强了导出声明的类型推断,让代码更具可读性和可维护性。

  • TypeScript 4.4 可以自动推断导出声明的类型,即使该类型没有显式声明。例如,下面的代码中,sum 函数的类型可以自动推断为 (a: number, b: number) => number
export function sum(a: number, b: number): number {
  return a + b;
}
  • TypeScript 4.4 还可以自动推断导出声明的类型参数。例如,下面的代码中,MyMap 类的类型参数 T 可以自动推断为 string
export class MyMap<T> {
  private map: Map<string, T>;

  constructor() {
    this.map = new Map();
  }

  get(key: string): T {
    return this.map.get(key);
  }

  set(key: string, value: T): void {
    this.map.set(key, value);
  }
}

改进的类型兼容性检查

TypeScript 4.4 改进了类型兼容性检查,使得代码更具健壮性。

  • TypeScript 4.4 引入了新的类型兼容性规则,使得联合类型和交叉类型更加兼容。例如,下面的代码中的 foo 变量可以赋值给 bar 变量,因为 string | number 类型兼容 number | string 类型:
let foo: string | number;
let bar: number | string;

foo = "hello";
bar = foo;
  • TypeScript 4.4 还改进了对泛型类型的兼容性检查。例如,下面的代码中的 MyArray 类的两个实例可以相互赋值,因为它们具有相同的泛型参数类型:
class MyArray<T> {
  private items: T[];

  constructor(items: T[]) {
    this.items = items;
  }

  get(index: number): T {
    return this.items[index];
  }

  set(index: number, value: T): void {
    this.items[index] = value;
  }
}

const array1 = new MyArray<number>([1, 2, 3]);
const array2 = new MyArray<number>([4, 5, 6]);

array1 = array2;