跳到主要内容

TypeScript 泛型实例

什么是TypeScript泛型?

TypeScript泛型是一种允许我们在定义函数、类或接口时使用类型参数的机制。通过泛型,我们可以编写更通用、可重用的代码,而无需为每种类型都编写单独的实现。泛型的核心思想是参数化类型,即类型本身可以作为参数传递。

为什么需要泛型?

假设我们需要编写一个函数,它可以返回传入的任何类型的值。如果没有泛型,我们可能需要为每种类型编写一个单独的函数:

typescript
function returnNumber(value: number): number {
return value;
}

function returnString(value: string): string {
return value;
}

这种方式显然不够优雅,而且随着类型的增加,代码会变得冗长且难以维护。泛型可以帮助我们解决这个问题。

泛型的基本语法

泛型的基本语法是在函数名或类名后面使用尖括号 <T> 来声明一个类型参数 TT 是一个占位符,表示任意类型。我们可以在函数体或类中使用这个类型参数。

泛型函数示例

以下是一个简单的泛型函数示例:

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

// 使用泛型函数
let output1 = identity<string>("Hello, TypeScript!");
let output2 = identity<number>(42);

在这个例子中,identity 函数可以接受任何类型的参数,并返回相同类型的值。我们通过 <T> 声明了一个类型参数 T,并在函数签名中使用它。

泛型类示例

泛型不仅可以用在函数中,还可以用在类中。以下是一个泛型类的示例:

typescript
class Box<T> {
private value: T;

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

getValue(): T {
return this.value;
}
}

// 使用泛型类
let stringBox = new Box<string>("TypeScript");
let numberBox = new Box<number>(100);

console.log(stringBox.getValue()); // 输出: TypeScript
console.log(numberBox.getValue()); // 输出: 100

在这个例子中,Box 类可以存储任何类型的值,并通过 getValue 方法返回该值。

泛型约束

有时我们希望泛型类型参数满足某些条件。例如,我们可能希望泛型类型参数必须具有某些属性或方法。这时可以使用泛型约束

泛型约束示例

假设我们有一个函数,它接受一个对象,并返回该对象的 length 属性。我们可以使用泛型约束来确保传入的对象具有 length 属性:

typescript
interface Lengthwise {
length: number;
}

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

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

在这个例子中,T extends Lengthwise 表示 T 必须满足 Lengthwise 接口的要求,即具有 length 属性。

实际应用场景

1. 泛型在数组操作中的应用

假设我们需要编写一个函数,它可以反转任何类型的数组。使用泛型可以轻松实现这一点:

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

let numbers = [1, 2, 3, 4, 5];
let strings = ["a", "b", "c", "d"];

console.log(reverseArray(numbers)); // 输出: [5, 4, 3, 2, 1]
console.log(reverseArray(strings)); // 输出: ["d", "c", "b", "a"]

2. 泛型在API响应中的应用

在处理API响应时,我们经常需要处理不同类型的数据。使用泛型可以使代码更加灵活:

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

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

// 使用泛型API响应
type User = { name: string; age: number };
let userResponse = fetchData<User>("https://api.example.com/user");
console.log(userResponse.data.name); // 输出: undefined (模拟数据)

总结

TypeScript泛型是一种强大的工具,它允许我们编写更通用、可重用的代码。通过泛型,我们可以避免为每种类型编写单独的实现,从而提高代码的灵活性和可维护性。泛型约束进一步增强了泛型的能力,使我们能够对类型参数施加限制。

在实际开发中,泛型广泛应用于数组操作、API响应处理等场景。掌握泛型的使用技巧,将帮助你编写更高效、更健壮的TypeScript代码。

附加资源与练习

  • 练习1:编写一个泛型函数 mergeObjects,它接受两个对象并返回它们的合并结果。
  • 练习2:创建一个泛型类 Stack,实现栈的基本操作(pushpoppeek)。
  • 推荐阅读:TypeScript官方文档中的泛型章节
提示

泛型是TypeScript中一个非常重要的概念,建议多加练习,熟练掌握其用法。