返回

一步一步学习 ts 泛型,快速提升编程能力

前端

TypeScript 泛型:解开代码可重用性和灵活性的秘密

泛型的本质

TypeScript 泛型是一种强大的工具,它允许你创建可重用的代码,就像变量可以存储数据类型一样,泛型可以存储类型类型。这提供了惊人的灵活性,让你可以创建函数和类来处理任何类型的数据,显著提高了代码的可维护性和灵活性。

基本使用场景

泛型函数的使用最为常见,你可以指定一个泛型参数来表示函数内部可接受的类型。例如,考虑一个函数,它取一个数组并返回其第一个元素:

function getFirstElement<T>(arr: T[]): T {
  return arr[0];
}

你可以在调用时指定泛型类型,例如:

const firstElement = getFirstElement<number>([1, 2, 3]); // firstElement 是 number 类型

泛型在类中的应用

泛型也可以应用于类,创建一个可以存储任何类型数据的类。考虑一个 Stack 类:

class Stack<T> {
  private data: T[] = [];

  push(item: T) { this.data.push(item); }
  pop(): T | undefined { return this.data.pop(); }
  peek(): T | undefined { return this.data[this.data.length - 1]; }
}

你可以使用该类来存储字符串、数字或任何其他类型的数据:

const stack = new Stack<string>();
stack.push("Hello");
stack.push("World");
console.log(stack.peek()); // 输出:"World"

高级泛型技巧

Partial 和 Omit:修改对象类型

PartialOmit 是两个有用的类型,它们可以修改对象的类型。Partial 将对象的所有属性标记为可选,而 Omit 允许你从对象中删除指定的属性:

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

type PartialPerson = Partial<Person>; // PartialPerson 的所有属性都是可选的
const partialPerson: PartialPerson = { name: "John" };

type OmitPerson = Omit<Person, "age">; // OmitPerson 没有 "age" 属性
const omitPerson: OmitPerson = { name: "Jane" };

类型组合:创建新的类型

TypeScript 允许你组合类型来创建新的类型。你可以使用 & 符号将类型组合成一个交叉类型,或使用 | 符号将类型组合成一个联合类型:

type Student = {
  name: string;
  grade: number;
};

type Teacher = {
  name: string;
  subject: string;
};

type StudentOrTeacher = Student | Teacher; // 联合类型允许存储 Student 或 Teacher 对象

const person: StudentOrTeacher = {
  name: "John",
  grade: 10,
};

// 使用类型保护来确定对象的类型
if ("grade" in person) {
  console.log(`Student: ${person.name}, Grade: ${person.grade}`);
} else {
  console.log(`Teacher: ${person.name}, Subject: ${person.subject}`);
}

AnyScript:将 JavaScript 转换为 TypeScript

AnyScript 是一个特殊类型,它允许你将 JavaScript 代码转换为 TypeScript 代码。这为你提供了在 TypeScript 代码中使用 JavaScript 函数的灵活性:

const fetch = (url: string) => {
  // JavaScript 代码转换为 TypeScript 代码
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open("GET", url);
    xhr.onload = () => {
      if (xhr.status === 200) {
        resolve(xhr.responseText);
      } else {
        reject(new Error(xhr.statusText));
      }
    };
    xhr.onerror = () => { reject(new Error("Network Error")); };
    xhr.send();
  });
};

结论

TypeScript 泛型是一个不可或缺的工具,它为代码带来了巨大的灵活性、可重用性和类型安全性。掌握泛型是成为一名熟练的 TypeScript 开发人员的关键,它可以帮助你编写更简洁、更可维护的代码。

常见问题解答

  1. 泛型和类型参数有什么区别?
    泛型是类型参数的占位符,用于表示可以在代码中使用的任何类型。
  2. 我可以使用多个泛型参数吗?
    是的,你可以使用多个泛型参数来表示不同的类型。
  3. 什么时候应该使用泛型?
    泛型适用于需要创建可重用代码或处理不同类型数据的情况。
  4. Partial 和 Omit 类型有什么区别?
    Partial 将所有属性标记为可选,而 Omit 允许你从类型中删除特定的属性。
  5. 如何检查对象的类型?
    你可以使用类型保护,例如 if ("propertyName" in object) 来检查对象的类型。