JSON 转 TypeScript 推断的工作原理
推断是对已解析 JSON 树的单次遍历。工具读取每个值,为其选择 TypeScript 类型,然后为找到的每个对象输出一个接口。
- 用浏览器原生解析器解析 JSON 样本,并以行/列提示拒绝格式错误的输入。
- 为每个值嗅探 TypeScript 类型——
string、number、boolean、null、数组或嵌套对象。 - 为每个嵌套对象根据父属性键派生接口名(例如
user.address成为Address接口)。 - 合并每个数组中的元素类型,使
{id: 1}和{id: 2, label: "x"}的列表生成含正确可选字段的联合类型。 - 应用您的选项(interface 还是 type、readonly、可选可空),并按依赖顺序输出声明,使文件无前向引用即可编译。
为什么要从 JSON 生成 TypeScript 类型?
- 大多数形状错误在响应类型被写下来后可在编译时捕获。从真实载荷推断接口替您完成了大部分工作,strict 模式会捕获文档中遗漏的字段。
- 将推断的接口与 Zod 或 io-ts 等运行时验证器配对,可使同一形状承担两项任务:开发时的编辑器自动补全,以及生产环境收到异常数据时的 400 错误响应。
- TypeScript 的语言服务只提示它知道的字段。一旦导入推断的接口,输入点号时自动补全立即生效——不再需要对响应进行
as any类型断言,然后在仓库里沮丧地 grep。 - 如果您即将编写 OpenAPI 规范,推断的接口是响应 schema 的快速初稿。您仍需手写示例和约束,但属性名和类型已经正确了。
常见应用场景
推断在真实载荷存在但 schema 不存在时最为有用。
- 在编写处理器之前为来自 Stripe、GitHub 或 Twilio 等服务的第三方 Webhook 载荷添加类型。
- 为内部 REST API 建立类型基础,使前端团队可以在后端接口上线当天就开始编写代码。
- 从观察到的 API 响应生成 Zod、io-ts 或 Valibot schema 的起点。
输出是什么样的?
给定一个 JSON 样本文档和根名称,生成器产生一棵接口树,每个嵌套对象对应一个接口。对于以下输入,根名称为 User:
粘贴 {"id":1,"name":"Alice","tags":["a","b"],"address":{"city":"Paris"}},根名称填 User,生成器产生:
export interface User {
id: number;
name: string;
tags: string[];
address: Address;
}
export interface Address {
city: string;
}
注意 address 被提升为独立命名的接口——这就是按依赖顺序输出的效果。相同的 JSON 换用 type 声明风格会输出 export type User = {...};开启 readonly 开关后,每个属性都会加上 readonly 修饰符。
生成器选项
声明风格
选择 interface(TypeScript 中对象形状的标准写法)或 type(如果您后续需要映射类型、条件类型或交叉类型则更方便)。两者运行时行为完全相同;选择是编码风格偏好。
可选可空字段
当采样值为 null 时,字段类型变为 T | null。开启此选项还会添加 ? 修饰符,使字段在 TypeScript 侧变为可选——当 API 有时完全省略键而非返回 null 时非常有用。
Readonly 修饰符
在每个属性声明前加 readonly,使输出的接口与不可变数据模型匹配。适用于 Redux state slice、冻结的 API 响应,或任何希望编译器标记意外修改的场景。
支持嵌套对象和数组吗?
支持。每个嵌套对象都成为一个以父属性键派生的命名接口,数组从内容推断元素类型。包含对象的数组会为每种对象形状生成一个接口,形状不一致时产生联合类型。
可选字段是如何推断的?
开启「将可空字段标记为可选」开关,任何采样值为 null 的字段都会在键上加 ? 修饰符,并在类型中加 | null。不开启该开关时,字段保持必填,类型仅为 T | null。
支持可辨识联合吗?
当数组包含混合形状的项,或字段同时携带某个值和 null 时,会输出基本联合类型。完整的可辨识联合推断(选取 type 或 kind 作为标签并拆分变体)需要多个样本——这已在规划中,但尚未在当前版本中实现。
可以从多个 JSON 样本推断类型吗?
目前不行——当前推断器每次读取一个样本。如果您有两个应共享接口的载荷(例如列表接口和单项接口),实用的变通方法是将它们合并为一个数组,从中生成,然后重命名生成的联合类型。多样本推断在路线图上,因为这是发现一个响应中存在而另一个中缺失的字段的唯一方法。
粘贴载荷,命名根节点,复制接口。整个流程在您的浏览器中运行,因此未发布的 API 或签名 Webhook 体都留在您的设备上。