跳到主要内容

TypeScript 泛型

泛型是TypeScript中一个强大的特性,它允许我们编写灵活且可重用的代码。通过泛型,我们可以创建适用于多种类型的函数、类和接口,而不必为每种类型编写重复的代码。

什么是泛型?

泛型(Generics)是一种在定义函数、接口或类时不预先指定具体类型,而在使用时再指定类型的机制。泛型的主要目的是提高代码的复用性和灵活性。

泛型的基本语法

在TypeScript中,泛型通常使用尖括号 <T> 来表示,其中 T 是一个类型变量。我们可以将 T 替换为任何类型。

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

在这个例子中,identity 函数接受一个类型为 T 的参数,并返回相同类型的值。T 是一个占位符类型,它可以是任何类型。

使用泛型

我们可以通过以下方式调用 identity 函数:

typescript
let output1 = identity<string>("Hello");
let output2 = identity<number>(42);

在这个例子中,output1 的类型是 string,而 output2 的类型是 number。泛型允许我们在调用函数时指定类型。

泛型约束

有时候,我们希望泛型类型具有某些特定的属性或方法。这时,我们可以使用泛型约束来限制类型。

typescript
interface Lengthwise {
length: number;
}

function loggingIdentity<T extends Lengthwise>(arg: T): T {
console.log(arg.length);
return arg;
}

在这个例子中,loggingIdentity 函数要求传入的参数必须具有 length 属性。这样,我们就可以在函数内部安全地访问 arg.length

泛型类和接口

泛型不仅可以用于函数,还可以用于类和接口。

泛型类

typescript
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

在这个例子中,GenericNumber 类使用泛型 T 来定义 zeroValueadd 方法。我们可以通过指定类型参数来创建不同类型的 GenericNumber 实例。

泛型接口

typescript
interface GenericIdentityFn<T> {
(arg: T): T;
}

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

let myIdentity: GenericIdentityFn<number> = identity;

在这个例子中,GenericIdentityFn 是一个泛型接口,它定义了一个函数类型。我们可以将 identity 函数赋值给 myIdentity,并指定类型参数为 number

实际应用场景

泛型在实际开发中有很多应用场景,例如:

  1. 数组操作:我们可以使用泛型来创建适用于任何类型数组的函数。

    typescript
    function reverse<T>(items: T[]): T[] {
    return items.reverse();
    }

    let numbers = reverse<number>([1, 2, 3]);
    let strings = reverse<string>(["a", "b", "c"]);
  2. API响应处理:在处理API响应时,泛型可以帮助我们定义返回数据的类型。

    typescript
    interface ApiResponse<T> {
    data: T;
    status: number;
    }

    function fetchData<T>(url: string): ApiResponse<T> {
    // 模拟API调用
    return {
    data: {} as T,
    status: 200
    };
    }

    let response = fetchData<{ name: string }>("/api/user");

总结

泛型是TypeScript中一个非常强大的特性,它允许我们编写灵活且可重用的代码。通过泛型,我们可以创建适用于多种类型的函数、类和接口,而不必为每种类型编写重复的代码。

提示

提示:在使用泛型时,尽量保持代码的简洁和可读性。避免过度使用泛型,以免增加代码的复杂性。

附加资源

练习

  1. 编写一个泛型函数 firstElement,它接受一个数组并返回数组的第一个元素。
  2. 创建一个泛型类 Box,它包含一个属性 value,并提供一个方法 getValue 来获取该属性的值。
  3. 使用泛型约束,编写一个函数 longest,它接受两个具有 length 属性的对象,并返回长度较长的那个对象。

通过完成这些练习,你将更好地理解泛型的概念及其在实际开发中的应用。