⭐ 觉得好用?收藏备用,下次直接打开
输入 JSON Schema
输入:空
输出 TypeScript
输出:等待输入

Schema 转 TypeScript 把一份 JSON Schema 转成等价的 TypeScript 类型定义,让前端代码从编辑期就能享受字段补全、类型检查、重构安全。所有转换在浏览器本地完成,不联网。

核心映射:

JSON SchemaTypeScript
type: "string"string
type: "integer" / "number"number
type: "boolean"boolean
type: "null"null
type: "array", items: TT[]
prefixItems: [A, B](2020-12)[A, B]
type: "object", properties + requiredinterface
enum: [...]字面量联合 "a" | "b"
const: X字面量 X
anyOf / oneOf联合 A | B
allOf交叉 A & B
$ref#/$defs/X引用类型 X
additionalProperties: T[k: string]: T 索引签名

与主流库的对齐点:字段按 required 列表决定必选 / 可选;对象转 interface、其它转 typedefinitions / $defs 提升为顶层类型,命名沿用 Schema 里的 key。description 字段会生成对应 TSDoc 注释(/** ... */)。

工具局限

  • integernumber 都映射为 TS 的 number(语言限制)
  • pattern / minLength / maximum运行时约束无法在类型系统表达,需要配合运行时校验器(如 Schema 校验器)
  • 不解析外部 $ref URL(如跨文件、跨域)
  • 复杂条件(if / then / elsedependentSchemas)转为 unknown

📍使用场景

  • 后端 Schema 同步前端类型后端给一份 JSON Schema,一键生成对应 TS 类型,前端直接 `import { User } from ...` 拿到编译期校验。
  • OpenAPI 响应结构转 TS从 `components.schemas` 里抽出一段 JSON Schema,本工具直接转成 interface;接口调用处自动补全字段。
  • 配置对象类型化项目有一份 `config.schema.json`,转成 TS 类型后 `config.ts` 里就能享受补全和错键检查。

常见问题

生成的是 `interface` 还是 `type`?

默认对象类型出 `interface`(`export interface User { id: number; name: string }`),其它(enum / union / primitive / tuple)出 `type`(比如 `export type Role = 'admin' | 'user'`)。`$defs` 和 `definitions` 里声明的子 Schema 会被提到顶层作为独立类型,根 Schema 用 `根类型名`(默认 `Root`,可改成 `User` 等)。

`anyOf` / `oneOf` / `allOf` 怎么映射?

anyOfoneOf 都转成 联合类型(`A | B`)——TypeScript 结构类型系统没有"严格互斥"的直接表达,工具按联合处理。allOf 转成 交叉类型(`A & B`)。如果需要严格互斥语义,请在生成的 TS 基础上手动加 discriminated union(按 `type` 字段区分)。

`$ref` 会被展开还是保留引用?

保留引用——`$ref: "#/definitions/Address"` 转成 TS 里的 `Address` 类型引用,前提是 `definitions` / `$defs` 里确实有这个名字。工具不会联网解析外部 `$ref`(如 `https://...`),遇到外部引用会转为 `unknown`。同文件内的循环引用(A 引 B、B 引 A)也能正确处理。

为什么 `integer` 变成了 `number`?

TypeScript 原生没有整数类型——`number` 统一表示所有数值,包括整数和浮点数。Schema 里的 `integer` 约束是运行时规则(由校验器保证),编译期通过 TS 类型系统无法表达。想要严格区分可以用 `integer` 分支类型,但会让类型接入成本飙升,工具默认不生成。

`enum` 会生成 TS `enum` 吗?

不会,生成联合字面量类型(`type Role = "admin" | "user" | "guest"`)。原因:TS `enum` 会在编译后产生运行时对象,侵入性高;联合字面量类型则纯在编译期,轻量且互操作性更好。这也是 `json-schema-to-typescript` 等主流库的默认做法。

`required` 以外的字段会怎样?

标记为可选(字段名后加 `?`)并允许 `undefined`。Schema 里 `required: ["id", "name"]` 时,`email`、`role` 这些没列入 required 的字段在 TS 里变成 `email?: string`。这与 JSON Schema 的默认语义一致:没列入 `required` 就是可以缺省。