0Pricing
TypeScript Academy · 课时

带类型的流式接口

在链式调用方法时,跟踪类型中不断累积的状态。

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

跟踪已设置的内容

普通构建器允许您随时调用 build(),即使必填字段尚未设置也是如此。我们可以使用泛型类型参数,在类型系统中跟踪累积状态,从而做得更好。

状态类型参数

我们为构建器提供一个泛型 S,用于记录到目前为止已经提供了哪些键。每次方法运行时,我们都会扩展 S,使其包含一个新键。

class Builder<S> {
  // S is a record of keys set so far, e.g. {} or { url: string }
  private data: Record<string, unknown> = {};
}

每个方法添加一个键

设置方法会返回一个新的类型化构建器,其 S 包含刚添加的键。运行时会存储该值,而类型也会相应扩展。

  set<K extends string, V>(key: K, value: V): Builder<S & Record<K, V>> {
    this.data[key] = value;
    return this as unknown as Builder<S & Record<K, V>>;
  }

交集技巧

表达式 S & Record<K, V> 会将之前的状态与新键取交集。调用两次后,该类型就能精确地了解这两个键。

type Empty = {};
type AfterUrl = Empty & Record<"url", string>;
type AfterBoth = AfterUrl & Record<"method", string>;
// AfterBoth = { url: string; method: string }

具体的流式构建器

这里的请求构建器会在每次调用中传递累积的类型结构。编译器始终确切知道存在哪些字段。

class Req<S> {
  private d: Record<string, unknown> = {};
  url(u: string): Req<S & { url: string }> {
    this.d.url = u; return this as any;
  }
  method(m: string): Req<S & { method: string }> {
    this.d.method = m; return this as any;
  }
}

链式调用时类型逐步扩展

链中的每次调用都会生成一个更具体的构建器类型。在编辑器中将鼠标悬停在结果上,可以看到累积的状态。

const partial = new Req<{}>().url("/x");
// type: Req<{ url: string }>
const full = partial.method("POST");
// type: Req<{ url: string; method: string }>

为什么要跟踪状态

类型携带已提供键的集合后,我们就可以进一步限制 build(),使其仅在必需键都存在时才能通过编译。状态参数是实现这一保证的基础。

读取累积的类型结构

您可以提取累积的类型结构来检查它。这可以确认构建器的类型准确反映了已经配置的内容。

type StateOf<T> = T extends Req<infer S> ? S : never;
type S1 = StateOf<Req<{ url: string }>>; // { url: string }

运行时保持简单

所有复杂性都存在于类型中。运行时,每个设置方法只需将一个值存储到对象中。类型断言(as any)负责将运行时对象连接到更丰富的编译时类型。

const r = new Req<{}>().url("/users").method("GET");
console.log("configured url and method");

将泛型状态作为记录清单

可以将 S 看作已设置内容的记录清单。方法会追加条目;构建步骤稍后可以读取这份清单,以决定是否允许构造对象。

权衡

类型级状态跟踪能够提供精确的集成开发环境反馈,并防止构建不完整的对象,但代价是需要少量类型断言和更高级的泛型。对于供许多人使用的接口来说,这种做法很有价值。

快速检查

快速检查本课内容。

回顾

流式类型化构建器携带一个泛型状态参数 S。每个设置方法都会将 S 与新键取交集(S & Record<K, V>),并返回一个更具体的构建器,让编译器能够精确记录已配置的字段。

常见问题解答

「带类型的流式接口」课时是免费的吗?

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

「带类型的流式接口」这节课中我会学到什么?

在链式调用方法时,跟踪类型中不断累积的状态。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

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

「带类型的流式接口」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 构建器模式基础
  2. 带类型的流式接口
  3. 强制执行必需步骤
  4. 不可变构建器
← 返回 TypeScript Academy