TypeScript 泛型,包教包会!
2023-09-08 11:14:56
前言
TypeScript 泛型是一把双刃剑。用好了,它能让你的代码简洁、优雅、可读性强;用不好,它就会变成一个烫手山芋,让你的代码变得难以理解和维护。
如果你正在学习 TypeScript,或者已经使用 TypeScript 一段时间了,但还对泛型感到困惑,那么这篇文章正是为你而写的。在本文中,我将以通俗易懂的语言,从基础概念到高级用法,带你全面了解 TypeScript 泛型。
什么是泛型?
泛型是一种允许你为函数或类定义参数化类型的方法。参数化类型是指一种类型,它可以在定义时接受一个或多个类型参数。例如,你可以定义一个函数 add()
,它可以接受两个任意类型的参数,并返回这两个参数的和。
function add<T>(a: T, b: T): T {
return a + b;
}
在这个函数中,<T>
是一个类型参数。它可以是任何类型。例如,你可以调用 add()
函数,并传入两个数字,它将返回这两个数字的和:
const sum = add(1, 2); // sum 为 number 类型
你也可以调用 add()
函数,并传入两个字符串,它将返回这两个字符串的连接:
const str = add("hello", "world"); // str 为 string 类型
泛型的优势
泛型具有以下几个优势:
- 代码复用性: 泛型可以让你编写可重用的代码。例如,你可以编写一个
max()
函数,它可以接受两个任意类型的参数,并返回这两个参数中的最大值。你可以使用这个函数来查找数字、字符串或任何其他可比较类型中的最大值。 - 类型安全: 泛型可以帮助你提高代码的类型安全性。在上面的
add()
函数中,类型参数T
确保了函数只能接受两种相同类型的参数。这可以防止你犯下类型错误,例如将数字与字符串相加。 - 可读性: 泛型可以提高代码的可读性。当你在使用泛型时,你不需要显式地指定函数或类的类型参数。这使得你的代码更加简洁和易于理解。
泛型的使用
泛型可以用于函数、类和接口。
泛型函数
你可以通过在函数名前面加上类型参数列表来定义一个泛型函数。例如,以下是一个计算两个数字和的泛型函数:
function add<T>(a: T, b: T): T {
return a + b;
}
这个函数可以接受两个任意类型的参数,并返回这两个参数的和。
泛型类
你可以通过在类名前面加上类型参数列表来定义一个泛型类。例如,以下是一个表示栈的泛型类:
class Stack<T> {
private stack: T[] = [];
push(item: T) {
this.stack.push(item);
}
pop(): T | undefined {
return this.stack.pop();
}
peek(): T | undefined {
return this.stack[this.stack.length - 1];
}
isEmpty(): boolean {
return this.stack.length === 0;
}
}
这个类可以存储任何类型的元素。你可以使用这个类来创建一个数字栈、一个字符串栈或任何其他类型的栈。
泛型的约束
在某些情况下,你可能希望对泛型类型参数进行约束。例如,你可能希望确保泛型类型参数只能是数字。你可以通过使用类型约束来实现这一点。
以下是如何对泛型类型参数进行约束:
function add<T extends number>(a: T, b: T): T {
return a + b;
}
在这个函数中,类型参数 T
被约束为只能是数字类型。这意味着你只能调用这个函数,并传入两个数字参数。
结语
泛型是 TypeScript 中一个非常强大的特性。它可以让你编写更灵活、更可重用和更类型安全的代码。我希望本文能帮助你更好地理解泛型,并开始在你的 TypeScript 代码中使用它。