本页译自英文原文。如有出入,以英文版本为准。
类型化客户端
DaloyJS 提供两种方式,以完全类型安全的方式调用你的 API。根据调用方的情况选择合适的一种。
1. 进程内类型化客户端(零代码生成)
适用于同一 monorepo 中的 TypeScript 调用方(测试、内部工具、Next.js server actions):
客户端以 operationId 为键,返回 {status, body, headers} 的可辨识联合,并且一切都从路由定义本身推断而来。不需要构建步骤。
路径参数
路径参数按整个分段替换,因此 :id 永远不会匹配到 :idx 内部,并且每个值都会被百分号编码到它自己的分段中。自 1.3.7 起,当参数缺失、为空、为 . 或 .. 时,生成的方法会在发出任何请求之前抛出 TypeError。URL 解析会解析点分段(即使写成 %2E%2E),从而悄悄改变调用目标,例如把 DELETE /orgs/:org/members/.. 变成 DELETE /orgs/:org。通配符路由(*path,或名为 wildcard 的单独 *)接受以 / 分隔的值;每个分段都会以同样的方式编码和检查。
2. Hey API SDK(跨语言、跨仓库、构建时生成)
对于 monorepo 之外或使用其他语言的调用方,请用 @hey-api/openapi-ts 生成一个完全类型化的 fetch SDK。
- 01路由app.route(...)
- 02generateOpenAPI@daloyjs/core/openapi
- 03openapi.json磁盘上的 OpenAPI 3.1 规范
- 04openapi-tsHey API 生成器
- 05类型化 SDKsdk.gen.ts · types.gen.ts
- 06调用方完全类型化的 fetch 调用
使用生成的 SDK
我该用哪一种?
| 使用场景 | 选择 |
|---|---|
| 同一仓库中的 TypeScript 调用方(测试、内部工具) | createInProcessClient |
| 位于其他仓库的 Web 应用 / React Native 移动端包 | Hey API SDK |
| 非 TypeScript 调用方(Python、Swift、Kotlin) | OpenAPI 文档 + 他们偏好的生成器 |
| 面向第三方的公开 SDK | Hey API SDK,作为独立的包发布 |
从 ts-rest 迁移过来?
ts-rest 是一个流行的契约优先库,它通过在基于适配器的服务端(Express、Fastify、NestJS、Next.js)和 fetch 客户端(initClient)之间共享一份契约(initContract),提供无需代码生成的端到端 TypeScript 类型。如果你喜欢这种模式,DaloyJS 会让你感到熟悉,只有两点不同。
第一,在 DaloyJS 中,路由定义就是契约,没有需要额外保持同步的独立契约对象。上面展示的进程内 createClient 为同一仓库中的 TypeScript 调用方提供了同样零代码生成、共享类型的体验。
第二,ts-rest 的类型安全仅限 TypeScript,并且要求客户端导入契约。DaloyJS 会从同一组路由生成一等公民的 OpenAPI 3.1 规范和 Hey API SDK,因此无法导入你的类型的调用方(其他仓库、其他语言、公开 SDK)也能覆盖到。在 ts-rest 中,OpenAPI 是一个可选的附加组件(@ts-rest/open-api)。DaloyJS 本身也是服务端和运行时,可在 Node、Bun、Deno、Cloudflare 和 Vercel 之间移植,而不是挂载在另一个框架之上的类型层。
| ts-rest | DaloyJS | |
|---|---|---|
| 契约来源 | 独立的 initContract 对象 | 路由定义本身 |
| 零代码生成的类型化客户端 | 有(initClient,仅限 TypeScript) | 有(createClient,仅限 TypeScript) |
| 跨语言 / 跨仓库客户端 | OpenAPI 附加组件(@ts-rest/open-api) | OpenAPI 3.1 + Hey API SDK,一等支持 |
| 服务端 | 基于 Express / Fastify / NestJS / Next.js 的适配器 | 内置,可跨运行时移植 |
| 运行时校验 | Standard Schema(Zod / Valibot / ArkType) | Standard Schema(Zod / Valibot / ArkType / TypeBox) |
| 安全默认值 | 自行解决 | 响应头和请求体限制默认开启;CSRF 和限流只需一行代码 |
需要一个更大的契约来验证生成器的输出?请把大型模拟 REST 演示(英文)作为压力测试场景,而不是使用最小化的教程应用。
最后更新: