Generate Typed Code from JSON — TypeScript, Python, Go, Rust & More
Convert JSON to typed code in 8 programming languages. See how type inference works, with before-and-after examples for TypeScript interfaces, Python dataclasses, Go structs, Rust serde, and more.
为什么从 JSON 生成代码?
每个使用 JSON API 的项目最终都需要类型化模型。你将一个示例响应复制到编辑器中,目测字段,然后开始手动编写接口或结构体。这是可行的——直到负载有 40 个字段、三层嵌套和一个多态对象数组。那时这就变得繁琐、容易出错且速度慢。
代码生成器消除了这个手动步骤。粘贴一个 JSON 示例,选择一种语言,几秒钟内就能得到生产就绪的类型定义。好处是显而易见的:
- 节省时间 — 为一个 50 字段的负载生成类型只需几秒钟,而不是几分钟。
- 类型安全 — 你的编译器或运行时会在它们到达生产环境之前捕获不匹配。
- 减少样板代码 — 不再手动编写获取器、设置器、JSON 标签或序列化注解。
- 一致性 — 每个团队成员从相同的源数据中获得相同的模型。
类型推断是如何工作的
JSON 到代码生成器读取你的示例数据并推断每个值的类型。字符串变为 string,数字根据小数点的存在变为 int 或 float,布尔值直接映射,null 生成一个可选/可空的包装。对象变为命名类型(结构体、类、接口),数组变为其元素的类型集合。
以下是 JSON 类型在不同语言中的映射:
| JSON 类型 | TypeScript | Python | Java | Go | Rust | Swift |
|---|---|---|---|---|---|---|
| string | string | str | String | string | String | String |
| number (int) | number | int | int | int64 | i64 | Int |
| number (float) | number | float | double | float64 | f64 | Double |
| boolean | boolean | bool | boolean | bool | bool | Bool |
| null | null | None | null | *T (指针) | Option<T> | T? |
| object | interface | dataclass | class (POJO) | struct | struct | struct (Codable) |
| array | T[] | list[T] | List<T> | []T | Vec<T> | [T] |
关键的见解是:生成器只知道它所看到的。如果你的示例数据中有 42 作为一个字段,而该字段也可以是 42.5,生成器将选择 int 而不是 float。使用具有代表性的示例数据以获得准确的类型。
示例输入
我们将在下面的示例中使用这个 JSON。它涵盖了字符串、数字、布尔值、一个嵌套对象和一个数组:
{
"id": 1,
"name": "Alice Johnson",
"email": "alice@example.com",
"active": true,
"score": 97.5,
"address": {
"street": "123 Main St",
"city": "Portland",
"zip": "97201"
},
"tags": ["admin", "editor"]
}
从 JSON 生成 TypeScript 接口
TypeScript 是最常见的目标。生成器为每个对象创建一个接口,使用字段名作为属性键:
interface Address {
street: string;
city: string;
zip: string;
}
interface Root {
id: number;
name: string;
email: string;
active: boolean;
score: number;
address: Address;
tags: string[];
}
每个字段都有类型,嵌套的 address 对象获得自己的接口,而 tags 从其内容推断为 string[]。你可以将其直接粘贴到项目中,并开始使用它,享受完整的自动补全和编译时检查。
从 JSON 生成 Python 数据类
Python 的 @dataclass 装饰器自动生成 __init__、__repr__ 和比较方法。结合类型提示,这是在 Python 中定义 JSON 模型的最简洁方式:
from dataclasses import dataclass
@dataclass
class Address:
street: str
city: str
zip: str
@dataclass
class Root:
id: int
name: str
email: str
active: bool
score: float
address: Address
tags: list[str]
将此与 dacite 或 cattrs 等库配合使用,可以直接将 JSON 字典反序列化为这些数据类实例。
从 JSON 生成 Java POJO
Java 需要更多的仪式——字段、构造函数和获取器/设置器。生成器在这里节省了最多的时间:
public class Address {
private String street;
private String city;
private String zip;
public String getStreet() { return street; }
public void setStreet(String street) { this.street = street; }
public String getCity() { return city; }
public void setCity(String city) { this.city = city; }
public String getZip() { return zip; }
public void setZip(String zip) { this.zip = zip; }
}
public class Root {
private int id;
private String name;
private String email;
private boolean active;
private double score;
private Address address;
private List<String> tags;
// getters and setters...
}
生成的 POJO 可以直接与 Jackson、Gson 或 Java 生态系统中的任何其他 JSON 序列化库一起使用。
从 JSON 生成 Go 结构体
Go 结构体使用字段标签来控制 JSON 编组。生成器生成符合 Go 习惯的代码,带有导出字段和 json:"..." 标签:
type Address struct {
Street string `json:"street"`
City string `json:"city"`
Zip string `json:"zip"`
}
type Root struct {
ID int64 `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
Active bool `json:"active"`
Score float64 `json:"score"`
Address Address `json:"address"`
Tags []string `json:"tags"`
}
这些标签确保 json.Unmarshal 将小写 JSON 键映射到导出的(大写)Go 字段。字段名称自动采用 Pascal 大小写,id 变为 ID,遵循 Go 命名约定。
从 JSON 生成 Rust 结构体
Rust 使用 serde crate 进行序列化。生成器添加必要的派生宏:
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
pub struct Address {
pub street: String,
pub city: String,
pub zip: String,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Root {
pub id: i64,
pub name: String,
pub email: String,
pub active: bool,
pub score: f64,
pub address: Address,
pub tags: Vec<String>,
}
使用 serde_json,你可以通过一次调用 serde_json::from_str 将 JSON 字符串反序列化为这些结构体。编译器强制确保每个字段都存在且类型正确。
从 JSON 生成 Swift Codable
Swift 的 Codable 协议使得内置 JSON 编码和解码变得简单,无需外部依赖:
struct Address: Codable {
let street: String
let city: String
let zip: String
}
struct Root: Codable {
let id: Int
let name: String
let email: String
let active: Bool
let score: Double
let address: Address
let tags: [String]
}
使用 JSONDecoder().decode(Root.self, from: data) 可以直接将 JSON 数据解析为这些结构体。Swift 自动从属性名称推断编码键。
处理嵌套对象和数组
嵌套对象是代码生成中最有趣的部分。当生成器在另一个对象内部遇到对象值时,它会创建一个单独的命名类型。命名约定通常基于字段名称:
- 一个名为
address的字段包含一个对象,生成一个名为Address的类型。 - 一个名为
shipping_details的字段生成ShippingDetails(Pascal 大小写)。 - 深度嵌套的对象遵循相同的模式递归——一个带有嵌套
coordinates对象的address生成Address和Coordinates类型。
对象数组的处理方式类似。如果 items 是一个对象数组,生成器检查第一个元素(或合并所有元素)以推断类型,并创建一个单数命名的类型,如 Item。
原始数组(["admin", "editor"])则比较简单——它们变为 string[]、Vec<String>、[]string 等,具体取决于目标语言。
提高生成代码质量的技巧
生成类型的质量完全取决于输入数据的质量。一些实用的技巧:
- 使用具有代表性的示例数据。 包含每个字段变体的至少一个示例。如果一个字段可以是
null,请包含一个空值,以便生成器将其标记为可选。 - 保持类型一致。 如果
id在某些记录中是数字,而在其他记录中是字符串,生成器必须选择一个或使用联合类型。首先清理你的示例数据。 - 重命名根类型。 大多数生成器将顶层名称默认为
Root。生成后将其重命名为有意义的名称,如User或ApiResponse。 - 在生成之前扁平化 如果你只需要结构的子集。将你的 JSON 示例修剪到你关心的字段。
- 检查边缘情况。 空数组(
[])在没有上下文的情况下无法被类型化。用至少一个元素填充它们,以便生成器知道项目类型。 - 审查和调整。 生成的代码是一个起点。你可能想重命名字段、调整整数宽度、添加验证注释或根据你的领域知识标记可选字段。
亲自尝试
立即生成类型化代码: 将任何 JSON 粘贴到我们的 JSON 到代码 生成器中,获取 TypeScript、Python、Java、Go、Rust、Swift、Kotlin 和 C# 的生产就绪类型。无需注册。