0Pricing
TypeScript Academy · 课时

递归类型定义

安全地编写引用自身的类型。

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

什么是递归类型

递归类型是在自身定义中引用自身的类型。这使您能够描述深度不受限制的数据结构。

type LinkedList<T> = {
  value: T;
  next: LinkedList<T> | null;
};
// next is the same type again, ending at null.

链表类型

经典示例是:每个节点包含一个 value,以及一个指向另一个节点的 next 指针;也可以使用 null 表示 chain 的结束。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const list: LinkedList<number> = {
  value: 1,
  next: { value: 2, next: null }
};
console.log(list.value, list.next?.value);

基础情况很重要

每个递归类型都需要一个终止条件,这里是 null,这样递归才能结束。没有它,类型就会无限加深。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const single: LinkedList<string> = { value: "only", next: null };
console.log(single.next);

构建更长的链

您可以按照需要嵌套任意深度;由于 next 本身就是链表或 null,该类型允许任意长度。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const chain: LinkedList<number> = {
  value: 10,
  next: { value: 20, next: { value: 30, next: null } }
};
console.log(chain.next?.next?.value);

遍历链表

函数可以沿着 chain 访问 next,直到到达 null。递归类型使整个过程具有完整的类型安全性。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function toArray<T>(list: LinkedList<T> | null): T[] {
  const out: T[] = [];
  let cur = list;
  while (cur) { out.push(cur.value); cur = cur.next; }
  return out;
}
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(toArray(l));

递归类型上的递归函数

递归类型天然适合与递归函数搭配使用。这里通过对 next 递归来计算长度。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function length<T>(list: LinkedList<T> | null): number {
  return list === null ? 0 : 1 + length(list.next);
}
const l: LinkedList<string> = { value: "a", next: { value: "b", next: null } };
console.log(length(l));

向链表前端添加元素

由于类型保持统一,构建新链表很容易:将现有链表包装为新头节点的 next 即可。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function prepend<T>(value: T, list: LinkedList<T> | null): LinkedList<T> {
  return { value, next: list };
}
const l = prepend(1, prepend(2, null));
console.log(l.value, l.next?.value);

可选终止符与可空终止符

您可以使用 null 终止,也可以将 next 设为可选。两者都能结束递归,请根据您希望如何表示末尾来选择。

type ListA<T> = { value: T; next: ListA<T> | null };
type ListB<T> = { value: T; next?: ListB<T> };
const a: ListA<number> = { value: 1, next: null };
const b: ListB<number> = { value: 1 };
console.log(a.value, b.value);

递归类型是惰性的

TypeScript 只会将递归类型展开到实际使用的深度。定义可以引用自身,而不会导致无限计算。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
// Using two levels only expands two levels.
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(l.next?.value);

映射链表

递归映射会转换每个值,同时保留结构,并返回一个形状相同的新链表。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
function mapList<T, U>(list: LinkedList<T> | null, fn: (v: T) => U): LinkedList<U> | null {
  if (list === null) return null;
  return { value: fn(list.value), next: mapList(list.next, fn) };
}
const l: LinkedList<number> = { value: 1, next: { value: 2, next: null } };
console.log(mapList(l, x => x * 10)?.value);

递归类型为何强大

自引用类型可以让您建模任意嵌套的数据、链表、树和 JSON,同时提供完整的类型安全性,并且在设计上没有固定的深度限制。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const l: LinkedList<boolean> = { value: true, next: { value: false, next: null } };
console.log(l.value, l.next?.value);

快速检查:递归类型

请测试您对递归类型定义的理解。

回顾:递归类型定义

您已经了解到,递归类型会引用自身,需要使用 null 之类的基础情况来终止,并且天然适合与递归函数搭配,以遍历、映射和构建链表。

type LinkedList<T> = { value: T; next: LinkedList<T> | null };
const l: LinkedList<number> = { value: 1, next: null };
console.log(l.value);

常见问题解答

「递归类型定义」课时是免费的吗?

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

「递归类型定义」这节课中我会学到什么?

安全地编写引用自身的类型。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

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

「递归类型定义」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 递归类型定义
  2. 树形结构的类型标注
  3. JSON 值类型
  4. 递归深度与限制
← 返回 TypeScript Academy