跳转到主要内容
模块 3 · 第 2 课(共 2)课程中的6/14~15 min
模块课程(2/2)

基本泛型

泛型(泛型编程)是 TypeScript 最强大的功能之一。它们允许您编写灵活的、可重用的组件、函数和接口,这些组件、函数和接口可以处理不同的数据类型,同时保持最大的类型安全性并避免使用 any。


通用函数

将泛型视为类型的变量。让我们考虑一个返回作为参数传递给它的值的函数:

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

字母 T (Type 的缩写)是类型的占位符。当我们调用 identity 时,TypeScript 会捕获传递参数的类型并自动将 T 设置为该类型:

TS
const str = identity<string>('Hello'); // T is string
const num = identity(42); // T is number (automatically inferred!)

通用接口和别名

泛型还可以应用于接口和类型别名来定义泛型容器或数据结构:

TS
interface Box<T> {
  content: T;
}

const stringBox: Box<string> = { content: 'TypeScript' };
const numberBox: Box<number> = { content: 42 };

多种类型参数

我们可以定义使用多个类型变量的函数或类型(例如 T 和 U):

TS
function mergeObjects<T, U>(obj1: T, obj2: U): T & U {
  return { ...obj1, ...obj2 };
}

通用约束

有时我们想限制泛型接受的类型。我们可以使用 extends 关键字来添加约束。

例如,如果我们希望泛型类型始终具有 length 属性(如字符串或数组):

TS
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:通用恒等函数

锻炼#ts.m3.l2.e1
尝试:0加载中...

完成泛型标识函数,使其接受泛型类型 T 的值参数并不加修改地返回它。

正在加载编辑器...
显示提示

返回类型必须与参数的泛型类型 T 相同。

3 次尝试后可用的解决方案

练习 2:通用包装盒

锻炼#ts.m3.l2.e2
尝试:0加载中...

定义一个名为 Box 的通用接口,它接受类型参数 T 并具有一个名为 content 的类型 T 的属性。

正在加载编辑器...
显示提示

使用接口 Box<T> { content: T; } 语法。

3 次尝试后可用的解决方案

练习 3:通用约束

锻炼#ts.m3.l2.e3
尝试:0加载中...

编写一个名为 getLength 的通用函数,它接受参数 arg。 arg 必须限制为具有长度属性(数字)的接口。该函数必须返回arg.length。

正在加载编辑器...
显示提示

将函数声明为 getLength<T extends HasLength>(arg: T): number 并返回 arg.length。

3 次尝试后可用的解决方案

练习 4:通用对

锻炼#ts.m3.l2.e4
尝试:0加载中...

定义一个具有两个属性的通用接口 Pair<T, U>:第一个属性为 T 类型,第二个属性为 U 类型。接下来,创建一个通用函数 makePair,它接受第一个(T 类型)和第二个(U 类型)并返回一个实现 Pair<T, U> 的对象。

正在加载编辑器...
显示提示

使用两个通用参数 Pair<T, U> 的语法并相应地定义 makePair。

3 次尝试后可用的解决方案