什么是 TypeScript 的泛型?

2024-08-26 11:05:40 339
TypeScript 的泛型(Generics)是一种强大的工具,允许你在定义函数、接口或类时不预先指定具体的类型,而是让用户在使用时传入具体的类型。泛型使得代码可以在保持类型安全的同时,更加灵活和可重用。

为什么使用泛型?

在 TypeScript 中,有时候我们希望函数或类能够处理多种类型的数据,而不局限于某一种特定类型。使用泛型可以让代码在处理不同类型时仍然保持类型安全,并且避免重复编写相似的代码。

泛型的基本语法

泛型使用尖括号 <T> 来表示,其中 T 是一个类型参数,具体的类型会在使用时传入。

function identity<T>(value: T): T {
    return value;
}

// 使用泛型函数
let num = identity<number>(10);  // num 的类型是 number
let str = identity<string>("Hello");  // str 的类型是 string

解释:

  • identity 函数接受一个类型参数 T,并返回相同类型的值。
  • 当调用 identity 时,可以传入具体的类型(如 numberstring),TypeScript 会自动推断出返回值的类型。

示例 1: 泛型函数

泛型函数可以处理多种类型,而不需要为每种类型编写单独的函数。

function echo<T>(value: T): T {
    return value;
}

let booleanValue = echo<boolean>(true);  // booleanValue 的类型是 boolean
let arrayValue = echo<number[]>([1, 2, 3]);  // arrayValue 的类型是 number[]

示例 2: 泛型接口

泛型接口允许你定义一个通用接口,可以与不同的类型一起使用。

interface Pair<T, U> {
    first: T;
    second: U;
}

let pair: Pair<string, number> = {
    first: "hello",
    second: 42
};

解释:

  • Pair<T, U> 是一个泛型接口,它有两个类型参数 TU
  • 在使用 Pair 接口时,我们指定 TstringUnumber

示例 3: 泛型类

泛型类可以定义一个适用于多种类型的类。

class Box<T> {
    content: T;

    constructor(content: T) {
        this.content = content;
    }

    getContent(): T {
        return this.content;
    }
}

let stringBox = new Box<string>("Hello");
let numberBox = new Box<number>(123);

console.log(stringBox.getContent());  // 输出: Hello
console.log(numberBox.getContent());  // 输出: 123

解释:

  • Box<T> 是一个泛型类,它有一个类型参数 T,表示存储内容的类型。
  • 在创建 Box 实例时,可以指定内容的类型,如 stringnumber

示例 4: 泛型约束

有时候,我们希望泛型参数只能是某些类型,这时可以使用泛型约束(extends 关键字)。

interface Lengthwise {
    length: number;
}

function logLength<T extends Lengthwise>(value: T): void {
    console.log(value.length);
}

logLength("Hello");  // 输出: 5
logLength([1, 2, 3]);  // 输出: 3

解释:

  • T extends Lengthwise 表示泛型参数 T 必须有 length 属性,这样可以确保 logLength 函数能够访问 length 属性。
  • 字符串和数组都具有 length 属性,因此可以传入 logLength 函数。

总结

泛型是 TypeScript 中用来创建灵活、可重用代码的重要特性。通过泛型,你可以编写在不同类型下都能正常工作的代码,而不用牺牲类型安全性。泛型可以应用于函数、接口和类等多种场景,为代码提供了极大的灵活性。