模块课程(2/2)
基本泛型
泛型(泛型编程)是 TypeScript 最强大的功能之一。它们允许您编写灵活的、可重用的组件、函数和接口,这些组件、函数和接口可以处理不同的数据类型,同时保持最大的类型安全性并避免使用 any。
通用函数
将泛型视为类型的变量。让我们考虑一个返回作为参数传递给它的值的函数:
function identity<T>(arg: T): T {
return arg;
}字母 T (Type 的缩写)是类型的占位符。当我们调用 identity 时,TypeScript 会捕获传递参数的类型并自动将 T 设置为该类型:
const str = identity<string>('Hello'); // T is string
const num = identity(42); // T is number (automatically inferred!)通用接口和别名
泛型还可以应用于接口和类型别名来定义泛型容器或数据结构:
interface Box<T> {
content: T;
}
const stringBox: Box<string> = { content: 'TypeScript' };
const numberBox: Box<number> = { content: 42 };多种类型参数
我们可以定义使用多个类型变量的函数或类型(例如 T 和 U):
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
return { ...obj1, ...obj2 };
}通用约束
有时我们想限制泛型接受的类型。我们可以使用 extends 关键字来添加约束。
例如,如果我们希望泛型类型始终具有 length 属性(如字符串或数组):
interface HasLength {
length: number;
}
function logLength<T extends HasLength>(arg: T): void {
console.log(arg.length); // Safe! We know arg has 'length'
}
logLength('Hello'); // Valid
logLength([1, 2, 3]); // Valid
// logLength(42); // Error: number does not have a length property!自己尝试一下
练习 1:通用恒等函数
完成泛型标识函数,使其接受泛型类型 T 的值参数并不加修改地返回它。
显示提示
返回类型必须与参数的泛型类型 T 相同。
3 次尝试后可用的解决方案
练习 2:通用包装盒
定义一个名为 Box 的通用接口,它接受类型参数 T 并具有一个名为 content 的类型 T 的属性。
显示提示
使用接口 Box<T> { content: T; } 语法。
3 次尝试后可用的解决方案
练习 3:通用约束
编写一个名为 getLength 的通用函数,它接受参数 arg。 arg 必须限制为具有长度属性(数字)的接口。该函数必须返回arg.length。
显示提示
将函数声明为 getLength<T extends HasLength>(arg: T): number 并返回 arg.length。
3 次尝试后可用的解决方案
练习 4:通用对
定义一个具有两个属性的通用接口 Pair<T, U>:第一个属性为 T 类型,第二个属性为 U 类型。接下来,创建一个通用函数 makePair,它接受第一个(T 类型)和第二个(U 类型)并返回一个实现 Pair<T, U> 的对象。
显示提示
使用两个通用参数 Pair<T, U> 的语法并相应地定义 makePair。
3 次尝试后可用的解决方案