JSON Schema 转 TypeScript

粘贴一段 JSON Schema,生成对应的 TypeScript interface,$ref、enum 和 required 都会处理。

关键字怎么对应

类型映射是固定的:string 直接是 string,integer 和 number 都是 number,boolean 是 boolean,null 是 null,array 按 items 生成 元素类型[](元素是联合类型时会加括号),object 生成一个 interface。带 properties 的 object 会单独命名成接口,嵌套对象用「父类型名 + 属性名转 PascalCase」拼出来,比如 meta.createdAt 对应 UserMeta。

required 数组里的属性是必填,其余一律加上 ?: 变成可选。字段名不是合法的 TypeScript 标识符(含短横线、点号等)时会用单引号包起来。写法上是 {"type": "string"} 这类标准 JSON Schema,也兼容 OpenAPI 3.0 里的 nullable: true,会给类型补上 | null。

$ref 和联合类型

本工具只解析文档内部的引用,也就是 #/definitions/XXX 和 #/$defs/XXX 这两种常见写法,把引用的那段 schema 生成成一个同名 interface(或类型别名),字段处直接用这个名字,不会把结构展开复制一遍。引用同一段只生成一次;自引用或互相引用(比如树节点里放子节点数组)也能处理,做法是先登记类型名再填内容,避免无限递归。

enum 会转成字面量的联合类型,例如 ["admin", "user"] 生成 'admin' | 'user';const 转成单个字面量。anyOf 和 oneOf 生成 | 连接的联合,allOf 生成 & 连接的交叉。additionalProperties 是对象时,没有固定字段的对象会写成 Record<string, T>;既写了 properties 又写了 additionalProperties 的,用索引签名兜底。

format 和局限

TypeScript 没有和 JSON Schema format 一一对应的类型,所以 date-time、email、uuid、uri 这些仍然输出 string,需要更精确的类型(例如 Date 或模板字面量)时得手动改。当一个 schema 省略了 type 只写了 format 时,工具会按 OpenAPI 的习惯推断:int32、int64、float、double 当成 number,其余 format 当成 string。生成的类型只描述结构,不做运行时校验:patternProperties、if/then/else、dependencies、数值范围这些约束不会体现在 TypeScript 里,需要数据校验时仍然要配 ajv 之类的校验器。另外数组的元组写法(items 是数组)会生成固定长度的元组类型 [A, B],而 2020-12 的 prefixItems 暂未处理。所有转换都在浏览器本地完成,schema 不会被上传。