Javascript is required

从 JSON API 样本推断 TypeScript 类型

多样本 API 响应推导 TypeScript 接口

对比多份 API 响应 Payload 自动识别可选属性 (?)、联合类型与 null 值。

根类型名称:
空数组默认类型:

Payload 样本 1

Payload 样本 2 (可选 - 用于检测可选字段与联合类型)

生成的 TypeScript 草稿

四组可重复的 TypeScript 推断案例

载入案例会替换两份样本,并重置全部推断选项。下方代码是初始选项对应的完整预期输出。

缺失字段与已观察到的 null

样本 1

{
  "id": 101,
  "email": "ada@example.test"
}

样本 2

{
  "id": 102,
  "email": null,
  "phone": "555-0100"
}

预期 TypeScript 草稿

export interface ApiUser {
  id: number;
  email: string | null;
  phone?: string;
}

初始选项: 根名称 ApiUser;开启可选推断;空数组默认 unknown[]。

核对结果: email 为 string 与 null 的联合类型,phone 为可选。关闭可选推断后 phone 必填,样本 1 不能作为完整 ApiUser 赋值。

键缺失与 null 值含义不同,均不能证明完整契约。

嵌套对象与对象数组元素

样本 1

{
  "id": 101,
  "profile": {
    "age": 20
  },
  "items": [
    {
      "sku": "A",
      "qty": 1
    }
  ]
}

样本 2

{
  "id": "102",
  "profile": {
    "age": "unknown",
    "nickname": "G"
  },
  "items": [
    {
      "sku": "B",
      "qty": null,
      "discount": true
    }
  ]
}

预期 TypeScript 草稿

export interface ApiOrder {
  id: number | string;
  profile: ApiOrderProfile;
  items: ApiOrderItemsItem[];
}

export interface ApiOrderProfile {
  age: number | string;
  nickname?: string;
}

export interface ApiOrderItemsItem {
  sku: string;
  qty: number | null;
  discount?: boolean;
}

初始选项: 根名称 ApiOrder;开启可选推断;空数组默认 unknown[]。

核对结果: id 与 profile.age 为 number 与 string 的联合类型。items 使用元素接口,其中 qty 为 number 与 null 的联合类型;nickname 和 discount 可选,关闭推断后变为必填。

已观察的值组成联合类型,字符串不会自动变为日期或枚举类型。

两份空数组没有元素类型证据

样本 1

{
  "tags": []
}

样本 2

{
  "tags": []
}

预期 TypeScript 草稿

export interface ApiTags {
  tags: unknown[];
}

初始选项: 根名称 ApiTags;开启可选推断;空数组默认 unknown[]。

核对结果: tags 为 unknown[]。选择 any[] 只改变该默认类型;另提供包含元素的样本会用观察到的元素类型推断。

空数组无法证明预期元素的真实类型。

数组根与需要引号的属性名

样本 1

[
  {
    "id": 101,
    "display-name": "Ada"
  }
]

样本 2

[
  {
    "id": "102",
    "display-name": null,
    "active": true
  }
]

预期 TypeScript 草稿

export type ApiPayload = ApiPayloadItemItem[];

export interface ApiPayloadItemItem {
  id: number | string;
  "display-name": string | null;
  active?: boolean;
}

初始选项: 根名称 api-payload;开启可选推断;空数组默认 unknown[]。

核对结果: 名称转换为 ApiPayload,同时输出根 type 别名与对象元素接口,display-name 保留引号。把根名称改为 9-response 后会得到 _9Response。

其他输入的生成名称可能冲突,请对照真实报文检查声明。

样本类型推断能告诉你什么

粘贴一到两份 JSON 报文。开启可选推断时,只在部分对象样本中出现的键会标记为可选;已观察的值用于推断 string、number、boolean、null、数组和嵌套对象类型。结果是待复核的草稿,可以复制或下载 .ts 文件。

对象根生成 interface,数组或基本值根生成 type 别名;对象数组同时输出元素接口。载入下方案例可以核对完整输出,并一起重置根名称、可选字段选项和空数组默认类型。

使用边界与限制条件

  • 可选只表示键在已观察的部分对象样本中缺失,null 则是值类型。所有样本都为 null 的字段推断为 null;这些结果不能证明完整 API 契约、枚举范围或未来行为。
  • 关闭可选推断会把缺失字段声明为必填,生成草稿可能无法接受某份输入样本。全部为空的数组默认使用 unknown[],也可选择 any[];有元素的其他样本会提供实际观察到的元素类型。
  • 不要把对象根与非对象根混在同次推断中。本页会停止生成,避免底层引擎静默忽略非对象样本。请将这些响应结构分开审阅。
  • 嵌套接口名由字段名转换而来,不同字段转换成相同标识符时可能发生冲突。需复核嵌套声明,并运行自己的编译与契约测试;编译通过本身不证明 API 模型准确。
  • 输入采用严格 JSON.parse,大整数可能丢失精度;推断在主线程执行,内存开销随输入变化,不承诺固定文件大小或处理速度。

常见问题与技术解答 (FAQ)

可选字段和允许 null 的字段有什么区别?▼

键在部分对象样本中缺失时,可生成 ?。键始终存在但值包含字符串和 null 时,生成 string 与 null 的联合类型。如果全部样本该字段都是 null,就只推断为 null,不会猜测未观察到的非空类型。

嵌套对象和对象数组如何参与推断?▼

已观察的嵌套对象会合并为命名接口,数组元素会合并为元素类型。对象数组根输出 type 别名和元素接口声明。推断依据样本,不执行 schema 校验,也不按记录的业务身份配对。

为什么空数组使用 unknown[] 或 any[]?▼

所有数组样本都为空时,没有元素类型证据,因此使用所选默认类型。如果另一份样本包含字符串,该字段就会推断为 string[]。any[] 会放宽检查;默认类型不能证明真实接口的数组元素类型。

生成结果能直接作为完整 API 契约吗?▼

请先复核。可选、null 和联合类型只反映输入样本;关闭可选推断可能使这些样本无法赋值,转换后的接口名也可能冲突。日期与枚举仍是 string,请结合 API 文档、更多响应和严格编译测试确认。