Frontend Academy · 课时

泛型:T、extends 与约束

编写泛型函数和接口,使用 extends 约束类型参数,并使用泛型默认值构建灵活的 API。

第 1 / 4 课13 个步骤

泛型:T、extends 与约束 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。

什么是泛型?

泛型让您可以编写适用于多种类型的函数、类和接口,同时保持类型安全。您无需为每种类型分别编写函数,而是编写一个由类型变量参数化的泛型函数。

一个简单的泛型函数

类型参数 T 在尖括号中声明。TypeScript 会根据参数类型推断出 T,因此调用位置无需显式注解。

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

identity(42);      // T is inferred as number, returns number
identity('hello'); // T inferred as string
identity<boolean>(true); // explicit

泛型接口与类型

使用泛型参数化接口和类型,以描述可复用的数据结构。

interface Box<T> {
  value: T;
  label?: string;
}

const numBox: Box<number> = { value: 42 };
const strBox: Box<string> = { value: 'hello', label: 'greeting' };

extends——约束泛型类型

使用 T extends SomeType 来限制 T 可以表示的类型。该函数只接受满足此约束的类型。

function getLength<T extends { length: number }>(item: T): number {
  return item.length; // safe: T is guaranteed to have length
}

getLength('hello');       // 5
getLength([1, 2, 3]);    // 3
getLength({ length: 7 }); // 7
// getLength(42);         // Error: number has no length

keyof 与泛型约束

keyof T 会生成 T 的属性键联合类型。它与泛型结合后,可以实现类型安全的属性访问。

function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user = { name: 'Alice', age: 30 };
getProperty(user, 'name');  // string
getProperty(user, 'age');   // number
// getProperty(user, 'foo'); // Error

泛型默认值

使用 T = DefaultType 为泛型参数提供默认类型。当存在合理的默认值,但调用方可以覆盖它时,就可以采用这种方式。

interface Paginated<T = unknown> {
  items: T[];
  total: number;
  page: number;
}

const rawPage: Paginated = { items: [], total: 0, page: 1 };
const typedPage: Paginated<User> = { items: [], total: 0, page: 1 };

多个类型参数

函数可以拥有多个相互独立的类型参数。

function zip<A, B>(arrA: A[], arrB: B[]): Array<[A, B]> {
  return arrA.map((a, i) => [a, arrB[i]]);
}

zip([1, 2, 3], ['a', 'b', 'c']);
// [[1,'a'], [2,'b'], [3,'c']]

泛型类

类也可以使用泛型。这在栈、队列和可观察存储等数据结构中很常见。

class Stack<T> {
  private items: T[] = [];
  push(item: T) { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
  peek(): T | undefined { return this.items.at(-1); }
  get size() { return this.items.length; }
}

const stack = new Stack<number>();
stack.push(1);
stack.push(2);
stack.pop(); // 2

异步泛型函数

异步泛型函数常用于带类型的 API 调用。

async function fetchJson<T>(url: string): Promise<T> {
  const res = await fetch(url);
  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  return res.json() as Promise<T>;
}

const users = await fetchJson<User[]>('/api/users');
const profile = await fetchJson<UserProfile>('/api/me');

在条件类型中使用 infer

条件类型中的 infer 关键字会根据某种模式提取类型。库代码常用它来提取函数的返回类型或数组的元素类型。

type ReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

type ElementType<T> = T extends Array<infer E> ? E : never;

type Fn = () => { name: string };
type Result = ReturnType<Fn>; // { name: string }

何时使用泛型

在以下情况下使用泛型:1)相同逻辑适用于多种类型;2)需要建立输入类型与输出类型之间的关系;3)正在构建可复用的数据结构或工具。不要只是为了使用而使用泛型——如果只有一种使用场景,具体类型会更清晰。

快速检查

约束 T extends { length: number } 能确保什么?

回顾:泛型

泛型可以参数化类型,使一个函数、类或接口适用于多种类型。T extends SomeType 会添加约束。keyof T 会生成属性键联合类型。使用 T = Default 可以设置泛型默认值。infer 可以在条件类型中提取类型。请使用泛型构建可复用的类型化工具和数据结构。

免费开始

用 AI 导师学习 HTML — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
41
课程
163

常见问题解答

「泛型:T、extends 与约束」课时是免费的吗?

是的 — 「泛型:T、extends 与约束」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。

「泛型:T、extends 与约束」这节课中我会学到什么?

编写泛型函数和接口,使用 extends 约束类型参数,并使用泛型默认值构建灵活的 API。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Frontend Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「泛型:T、extends 与约束」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Frontend Academy 课中编写并运行代码吗?

能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 泛型:T、extends 与约束
  2. 工具类型:Partial、Required、Pick 与 Omit
  3. 映射类型与条件类型
  4. 类型收窄:typeof、instanceof 与可辨识联合
← 返回 Frontend Academy