返回

入门指南:如何使用泛型让你的 TypeScript 代码更灵活

前端

泛型:TypeScript 中的可重用代码利器

TypeScript 中的泛型是一个强大的特性,它允许我们创建通用的代码,可以用于不同的数据类型,而无需重复编写代码。这大大提高了代码的可重用性和灵活性。

泛型函数

泛型函数接受未知类型的参数,允许我们在运行时动态指定数据类型。例如,我们可以创建一个计算数组中元素平均值的泛型函数:

function average<T>(arr: T[]): number {
  let sum = 0;
  for (let i = 0; i < arr.length; i++) {
    sum += arr[i];
  }
  return sum / arr.length;
}

const numbers = [1, 2, 3, 4, 5];
const averageNumber = average(numbers);
console.log(averageNumber); // 3

const strings = ['a', 'b', 'c', 'd', 'e'];
const averageString = average(strings);
console.log(averageString); // NaN

在这个示例中,average 函数接受一个数组作为参数,并返回数组中元素的平均值。泛型参数 T 允许该函数处理任何类型的数据,包括数字和字符串。

泛型接口

泛型接口定义了一组方法和属性,这些方法和属性可以用于不同类型的数据。例如,我们可以创建一个表示对象的泛型接口:

interface IObject<T> {
  key: string;
  value: T;
}

const obj1: IObject<number> = { key: 'age', value: 25 };
const obj2: IObject<string> = { key: 'name', value: 'John' };

在这个示例中,IObject 接口定义了一个具有 key 和 value 属性的对象。泛型参数 T 允许该接口用于任何类型的数据,包括数字和字符串。

泛型类

泛型类允许我们创建通用的类,这些类可以存储和处理不同类型的数据。例如,我们可以创建一个栈类:

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

  push(item: T) {
    this.arr.push(item);
  }

  pop(): T | undefined {
    return this.arr.pop();
  }

  peek(): T | undefined {
    return this.arr[this.arr.length - 1];
  }

  isEmpty(): boolean {
    return this.arr.length === 0;
  }
}

const numbersStack = new Stack<number>();
numbersStack.push(1);
numbersStack.push(2);
numbersStack.push(3);
const poppedNumber = numbersStack.pop();
console.log(poppedNumber); // 3

const stringsStack = new Stack<string>();
stringsStack.push('a');
stringsStack.push('b');
stringsStack.push('c');
const poppedString = stringsStack.pop();
console.log(poppedString); // c

在这个示例中,Stack 类定义了一个可以存储和处理任何类型数据的栈。泛型参数 T 允许该类用于任何类型的数据,包括数字和字符串。

泛型的优势

泛型提供了以下优势:

  • 可重用性: 泛型代码可以用于不同的数据类型,而无需重复编写代码,提高了可重用性。
  • 灵活性: 泛型允许我们在运行时动态指定数据类型,提供了更大的灵活性。
  • 代码一致性: 泛型代码可以确保代码在不同的数据类型上保持一致的行为,提高了代码维护性。
  • 类型安全性: TypeScript 会检查泛型代码中的类型,确保类型安全,防止类型错误。

常见问题解答

  1. 什么是泛型?
    泛型是 TypeScript 中的参数类型,允许我们在定义函数、接口或类时不必预先指定具体的类型,而在使用的时候再指定类型。

  2. 泛型的优势是什么?
    泛型提供了可重用性、灵活性、代码一致性和类型安全等优势。

  3. 如何使用泛型函数?
    泛型函数在定义时使用尖括号 (<>) 声明泛型参数,并在使用时指定具体的类型。

  4. 如何使用泛型接口?
    泛型接口在定义时使用尖括号 (<>) 声明泛型参数,并在使用时指定具体的类型。

  5. 如何使用泛型类?
    泛型类在定义时使用尖括号 (<>) 声明泛型参数,并在使用时指定具体的类型。