深入学习 TypeScript | 青训营

138 阅读4分钟

深入探索 TypeScript 类型体操

TypeScript,作为一门由微软开发的编程语言,是JavaScript的一个超集,它引入了静态类型检查,使得在开发过程中能够更早地发现潜在的错误。除此之外,TypeScript还拥有丰富的类型系统,允许开发者进行高级的类型体操,从而在编码过程中更加灵活和安全。本文将深入探讨 TypeScript 中的类型体操,展示其强大的特性和用法。

类型基础

在 TypeScript 中,类型是一切的基础。可以使用基本类型如 numberstringboolean,也可以创建自定义类型,甚至可以组合类型以实现更复杂的数据结构。

基本类型

let age: number = 25;
let name: string = "Alice";
let isStudent: boolean = true;

自定义类型

type Point = {
  x: number;
  y: number;
};

let origin: Point = { x: 0, y: 0 };

类型推断

TypeScript 具备强大的类型推断能力,使得开发者不必显式地为每个变量都指定类型。

let favoriteColor = "blue"; // TypeScript 推断 favoriteColor 为 string 类型

联合类型和交叉类型

联合类型允许变量具有多种可能的类型,而交叉类型则表示一个对象同时具有多种类型的属性。

type Result = number | string;

let response: Result = 200; // 或者 "OK"
type Dog = { name: string; woof: () => void };
type Cat = { name: string; meow: () => void };

type Pet = Dog & Cat;

let myPet: Pet = { name: "Fido", woof: () => {}, meow: () => {} };

类型保护与类型断言

TypeScript 允许使用类型保护来缩小变量的类型范围,增加代码的可读性和安全性。

function printLength(value: string | string[]): void {
  if (typeof value === "string") {
    console.log(value.length); // 在此块中,value 被类型缩小为 string
  } else {
    console.log(value.length); // 在此块中,value 被类型缩小为 string[]
  }
}

此外,开发者还可以使用类型断言来手动告诉编译器变量的实际类型。

let userInput: unknown = "Hello, TypeScript!";

let strLength: number = (userInput as string).length;

条件类型

条件类型是 TypeScript 类型系统中的高级特性,它允许根据类型关系进行条件分支。这对于编写泛型类型非常有用。

type Check<T> = T extends string ? boolean : number;

let result: Check<"hello"> = true; // 此时 result 的类型为 boolean

映射类型

TypeScript 提供了映射类型,允许开发者以一种类型作为模板,从而转换另一种类型。

type Optional<T> = {
  [P in keyof T]?: T[P];
};

interface Person {
  name: string;
  age: number;
}

let optionalPerson: Optional<Person> = { name: "Bob" };

keyof 与索引访问类型

keyof 关键字用于获取类型的所有属性名称,结合索引访问类型,可以在编译时获取对象属性的值类型。

type Point = { x: number; y: number };
type XCoordinate = Point["x"]; // 此时 XCoordinate 的类型为 number

类型级联

类型级联允许开发者通过连续调用方法来操作类型,从而创建新的类型。

type Person = {
  name: string;
  age: number;
};

type PersonWithAddress = Person & {
  address: string;
};

type PersonWithAddressAndPhone = PersonWithAddress & {
  phone: string;
};

infer 关键字

infer 关键字用于从泛型类型中提取类型信息,通常在条件类型中使用。

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

分布式条件类型

分布式条件类型是 TypeScript 中的一项高级特性,它允许条件类型在联合类型上进行分布式运算。

type UnboxArray<T> = T extends Array<infer U> ? U : T;

type Unboxed = UnboxArray<string[] | number[]>; // 此时 Unboxed 的类型为 string | number

类型的递归与递归条件类型

类型的递归允许类型引用自身,递归条件类型则通过条件判断实现递归类型的构建。

type TreeNode<T> = {
  value: T;
  left: TreeNode<T> | null;
  right: TreeNode<T> | null;
};

keyof 和映射类型的结合运用

keyof 和映射类型的结合运用允许开发者在类型上进行操作,从而创建新的类型。

type PrefixAllProps<T, Prefix> = {
  [K in keyof T as `${Prefix}${K}`]: T[K];
};

interface Person {
  name: string;
  age: number;
}

type PrefixedPerson = PrefixAllProps<Person, "prefix_">;

总结

TypeScript 的类型系统赋予开发者强大的能力,可以进行复杂的类型体操。从基本类型到高级类型,从类型保护到类型断言,从条件类型到映射类型,每个特性都为开发者提供了更精确、更安全的代码编写方式。通过不断深入学习和实践,开发者可以在 TypeScript 的世界中体验到类型体操的乐趣与成就感。