ZeroTool Workbench
JSON 转 TypeScript 生成器
从任意 JSON 生成 TypeScript interface 声明。支持嵌套对象、数组、联合类型和可选属性,纯浏览器运行,免费在线工具。
使用方法
- 将 JSON 粘贴或输入到左侧面板,工具会实时验证并高亮错误。
- 可选:设置 Root interface name(默认:
RootObject)。 - 勾选 Make properties optional 可将所有字段标记为
?可选。 - 勾选 Use type instead of interface 可将输出关键字改为
type。 - 点击 Generate TypeScript 生成接口定义。
- 点击 Copy 将输出复制到剪贴板。
类型推断规则
null→ 可选的null(field?: null)- 字符串 →
string - 数字 →
number - 布尔值 →
boolean - 空数组 →
unknown[] - 对象数组 → 合并接口 +
ItemName[] - 混合类型数组 → 联合类型,如
(string | number)[] - 嵌套对象 → 独立具名接口
示例
输入以下 JSON:
{"user": {"name": "Alice", "age": 30}, "tags": ["admin", "user"]}
工具生成:
interface RootObject {
user: User;
tags: string[];
}
interface User {
name: string;
age: number;
}
示例:API 响应
{
"user": {
"id": 42,
"name": "Alice",
"email": "[email protected]",
"roles": ["admin", "editor"],
"preferences": { "theme": "dark", "notifications": true },
"lastLogin": null
},
"pagination": { "page": 1, "perPage": 20, "total": 143 }
}
生成:
interface RootObject {
user: User;
pagination: Pagination;
}
interface User {
id: number;
name: string;
email: string;
roles: string[];
preferences: Preferences;
lastLogin?: null;
}
interface Preferences {
theme: string;
notifications: boolean;
}
interface Pagination {
page: number;
perPage: number;
total: number;
}
根接口排在最前,嵌套接口按出现顺序跟在后面。null 值会被写成类型 null 并标为可选,因为一个样本看不出字段有值时是什么类型。对照 API 文档后,改成 lastLogin: string | null 之类的写法。
示例:数组元素结构不同
{
"items": [
{ "id": 1, "name": "a", "tags": [] },
{ "id": 2, "price": 9.5, "tags": ["x", 1] }
],
"messages": [
{ "type": "text", "content": "hi" },
{ "type": "image", "url": "/a.png" }
]
}
生成:
interface RootObject {
items: ItemsItem[];
messages: MessagesItem[];
}
interface ItemsItem {
id: number;
name?: string;
tags: (unknown[] | (string | number)[]);
price?: number;
}
interface MessagesItem {
type: string;
content?: string;
url?: string;
}
数组中的所有对象会合并:只在部分元素里出现的键加 ?。messages 实际上是按 type 区分的两种结构,合并后的接口会接受「text 消息带 url」这类无效组合,建议改写成可辨识联合类型(TypeScript 手册:Narrowing):
type Message =
| { type: "text"; content: string }
| { type: "image"; url: string };
示例:两个对象用了同一个键名
{
"order": { "id": "A-1001", "meta": { "createdBy": "alice", "source": "web" } },
"payment": { "status": "paid", "meta": { "provider": "stripe", "fee": 0.3 } }
}
生成
interface RootObject {
order: Order;
payment: Payment;
}
interface Order {
id: string;
meta: Meta;
}
interface Meta {
createdBy: string;
source: string;
}
interface Payment {
status: string;
meta: PaymentMeta;
}
interface PaymentMeta {
provider: string;
fee: number;
}
order.meta 得到名称 Meta。payment.meta 字段不同,所以单独生成一个接口,名称前加上父级:PaymentMeta。若它的字段与 order.meta 相同,两者共用 Meta。把两者合并成一个所有字段都可选的 Meta,会接受两个接口都不会返回的对象,所以每种结构各有自己的类型。名称仍被占用时加数字(Meta2)。即使嵌套键与根名称相同,根接口也保留你填写的名称。
需要手动调整的地方
null字段:把?: null改成真实类型加| null。- 空数组:
[]生成unknown[],需要补上元素类型。 - 日期:ISO 8601 字符串和 Unix 时间戳分别保持
string、number。 - 不是合法标识符的键(
user-name、2fa)会加引号输出,这在 TypeScript 中是合法的。 PaymentMeta、Meta2这类名称由 JSON 键名生成,可按业务含义改名。- 键名无法生成合法类型名时(
2fa、空键名),接口名加前缀T(T2fa);属性本身仍用带引号的原键名。
限制
- 输入必须是合法 JSON(不能有注释或末尾逗号),报错信息会给出位置。
- 类型只来自你粘贴的样本。样本里是字符串、线上有时是数字的字段,仍会是
string。 - 勾选使用 type 替代 interface 后,每个声明写成
type Name = { ... };状态栏仍显示「接口」。
FAQ
这个工具生成什么?
它从 JSON 对象生成 TypeScript interface(或 type alias)声明。每个嵌套对象都会被提取为独立的具名接口;数组中的混合类型会生成联合类型。
嵌套对象如何处理?
每个嵌套对象字段会被提取为单独的接口,命名方式为字段名的 PascalCase。例如字段 'address' 对应 'Address' 接口,父接口引用该名称。
对象数组如何处理?
如果数组包含多个对象,所有对象的字段会合并为一个 item 接口。仅部分对象中存在的字段会被标记为可选。
'Make properties optional' 选项有什么用?
勾选后,所有生成接口的每个属性都会加上 '?' 后缀,变为可选。适合期望接收不完整数据或需要宽松类型定义的场景。
interface 和 type 有什么区别?
两者都可以描述对象结构。'interface' 支持声明合并,是对象类型的惯用写法;'type' 更灵活,还可以表示基本类型、联合类型和元组。勾选 'Use type instead of interface' 可切换输出关键字。
数据会发送到服务器吗?
不会。整个类型推断引擎完全在浏览器中运行,数据不会离开你的设备。