跳到主要内容

智能转换:JSON Schema To TypeScript定义 — Numio

使用 json-schema-to-typescript 将 JSON Schema 编译为 TypeScript interface。未列在 "required" 中的属性变为可选,对象会带上索引签名,除非 additionalProperties 为 false。

你的 API 发布了 JSON Schema 文件,你想为使用这些数据的客户端代码生成对应的 interface。

JSON Schema

TypeScript

适用场景

  • 你的 API 发布了 JSON Schema 文件,你想为使用这些数据的客户端代码生成对应的 interface。
  • 你的配置文件由 schema 校验,想在加载配置的地方获得类型检查。

使用方法

  1. 将 JSON Schema 粘贴到 JSON Schema 面板。"title" 决定 interface 名称;没有时根类型命名为 MySchema。
  2. 输入时即在浏览器中转换;页面没有任何设置,也不会添加横幅注释。
  3. 从 TypeScript 面板复制 interface。页面会用 Prettier 格式化,因此使用两个空格缩进且不带分号。

JSON Schema

{
  "title": "Address",
  "type": "object",
  "properties": {
    "street": { "type": "string", "minLength": 1 },
    "zip": { "type": "string", "pattern": "^[0-9]{5}$" },
    "country": { "enum": ["US", "CA"], "default": "US" },
    "unit": { "type": ["integer", "null"] },
    "lines": { "type": "array", "items": { "type": "string" }, "maxItems": 3 },
    "geo": { "type": "object", "required": ["lat", "lng"],
      "properties": { "lat": { "type": "number" }, "lng": { "type": "number" } } }
  },
  "required": ["street", "zip"]
}

TypeScript interface

export interface Address {
  street: string
  zip: string
  country?: "US" | "CA"
  unit?: number | null
  lines?: [] | [string] | [string, string] | [string, string, string]
  geo?: {
    lat: number
    lng: number
    [k: string]: unknown
  }
  [k: string]: unknown
}

功能与限制

没有 "additionalProperties": false 的对象会带上 [k: string]: unknown,因此类型中仍允许额外的键。

数组上的 maxItems 会展开为元组的联合类型,如示例中的 "lines"。

#/definitions/Tag 这类本地 $ref 会变为单独导出的 interface。

页面会用不带分号的 Prettier 处理结果,这也会去掉 "US" | "CA" 这类联合类型外多余的括号。

FAQ

null 值如何定义类型?

"type": ["integer", "null"] 会变为 (number | null)。integer 和 number 都映射为 number。

如何去掉 [k: string]: unknown?

在每个对象 schema 中添加 "additionalProperties": false,索引签名就会省略。

根 interface 如何命名?

取 schema 的 "title" 并转换为 PascalCase("Example Schema" 变为 ExampleSchema)。没有 title 时名称为 MySchema。

schema 会发送到服务器吗?

不会。json-schema-to-typescript 的 compile 函数在本页面的浏览器中运行。

规范与参考资料