接口类型怎么生成?JSON 转 TS 与 SQL 转实体类

2026-10-15约 9 分钟开发辅助涉及 5 个工具

对着接口返回手敲类型定义,是既慢又容易出错的事:字段少写一个、类型标错一次,编译期不会报,运行时才炸。这篇讲怎么从已有数据反向生成类型,以及生成后必须手工补哪几处。

核心要点
  • 手写类型定义的风险在于漏字段不会报错,只有运行到那一步才会出问题,而生成式做法能保证字段集合与真实数据一致
  • JSON 只有 number 一种数字类型,无法区分 int 与 float,所以整数键生成 number 符合运行时实际
  • 字段值为 null 时生成器只能推断为 null 或 any,这类字段必须手工改成可空联合类型,否则类型过窄
  • 从 CREATE TABLE 生成实体类时,DDL 里的长度与精度不会被保留,字段是否可空则要看列定义有没有 NOT NULL
  • 命名风格混用(接口用驼峰、数据库用下划线)是跨层开发里最多的低级 bug 来源,统一转换能一次改完
  • JSON 转 XML 时数组会变成重复标签、属性用 @ 前缀表示,这两个约定在双向转换时都必须遵守才能往返一致

#手写类型定义的问题不在慢

手写类型定义的真正风险是漏字段不会报错 —— 少写一个属性编译器不会提醒你,只有代码跑到读取那个字段时才会暴露,此时往往已经上线。

从真实数据反向生成就没有这个盲区:字段集合直接来自样本,不可能漏。生成后你要做的只是修正推断不到位的类型,这比从零手写快得多,也更准。

你想做的事用什么生成输出
接口响应 → 前端类型JSON 转 TS 接口TypeScript 接口定义
建表语句 → 后端实体SQL 转实体类Java / C# / TypeScript
结构 → 多语言模型JSON 转 Java Bean各语言实体类
命名风格不统一变量命名转换7 种风格互转

#从接口响应生成 TypeScript 类型

JSON 的数字类型在生成时会被统一推断为 number,这是正确的:JavaScript 运行时本来就不区分整数和浮点数。

用 JSON 转 TS 接口 的典型流程:

  1. 复制一份真实接口响应(要包含所有可能出现的字段,见下方提示)
  2. 粘进输入框,实时生成类型定义
  3. 选择嵌套对象是展开成独立接口还是内联
  4. 数组可选 T[] 或 Array<T> 风格,按团队规范决定
  5. 设置根接口名,复制或下载 .ts 文件
注意

样本决定质量。如果拿到的响应里某个可选字段恰好没有值,生成器就无法知道它的存在 —— 而且 JSON 里字段值为 null 时,推断结果可能是 null 或 any,这两种都不是你想要的可选字段类型。生成后必须手工把这几个字段改成 string | null 这类联合类型。

类型推断的对应关系大致如下,了解之后就能预判哪些需要手工改:

JSON 值生成类型需要手工修正的情况
"abc"string若是日期字符串,可改为 string + 注释或 Date
123 / 1.5number若是 ID 且超过 2^53,考虑用 string
trueboolean一般无需修改
nullnull 或 any几乎总需要改成可空联合类型
[...] 空数组any[] 或 never[]必须手工填入元素类型
{...}独立接口或内联对象按嵌套深度决定是否展开

#从 CREATE TABLE 生成实体类

DDL 里包含的信息比 JSON 多,所以生成的实体类质量通常更高:字段是否可空、主键、字段注释都能直接映射。

用 SQL 转实体类 时把完整的建表语句贴进去,它会解析表名、字段名、类型与注释,支持三种输出:

  • Java:字段带 @Id 主键注解,类型按映射表转换
  • C#:生成属性风格,含可空标记
  • TypeScript:适合前后端同构项目
说明

VARCHAR(255) 这类长度约束不会带到实体类里,因为实体类通常不关心存储长度;但 NOT NULL 会影响字段是否可空,这条一定要核对。另外数据库的 DATETIME 映射到 Java 时常见做法是 LocalDateTime,映射到 TypeScript 时则是 string,语言间的差异需要在生成后手工统一。

#命名风格不统一是隐性成本

接口用驼峰、数据库用下划线、常量用全大写 —— 这种跨层不一致是低级 bug 最常见来源,而且分散在很多文件里,很难一次找全。

用 变量命名转换 输入任意一种风格的名称,它会智能识别单词边界并给出 7 种风格的对应写法:

风格示例典型使用场景
camelCaseuserNameJavaScript / Java 变量与字段
PascalCaseUserName类名、React 组件名
snake_caseuser_namePython、数据库列名
kebab-caseuser-nameCSS 类名、URL 路径
CONSTANT_CASEUSER_NAME常量、环境变量
dot.caseuser.name配置键、国际化 key
Title CaseUser Name展示文本、标签

它的拆分逻辑能处理下划线、中划线、空格、驼峰边界和数字边界,所以 HTTPServerURL、user_name、user-name 都能拆对。

技巧

批量改名时先在 变量命名转换 里确认拆分结果是否正确,再去做全局替换。像 ID、URL 这类全大写缩写,不同工具的处理方式不一致,确认过再动手能省一次回滚。

#JSON 与 XML 互转的两个约定

数组转成重复标签、属性用 @ 前缀表示,这两个约定是 JSON 与 XML 往返转换能对上的前提。

用 JSON 转 XML 双向转换时:

JSON
{
  "user": {
    "@id": "1001",
    "name": "张三",
    "tags": ["前端", "后端"]
  }
}

对应生成的 XML 是:

XML
<user id="1001">
  <name>张三</name>
  <tags>前端</tags>
  <tags>后端</tags>
</user>

理解这两点就够用了:@id 表示这是属性而不是子元素;tags 数组变成了两个同名标签。反向往回转时,同名标签会被还原成数组 —— 但如果原 XML 只有一个 <tags>,转回 JSON 时它会变成单个字符串而不是数组,这是 XML 本身的歧义,不是转换错误。

#什么时候该用哪个工具

你的输入想要的输出用哪个
接口返回的 JSONTypeScript 类型JSON 转 TS 接口
CREATE TABLE 语句Java / C# / TS 实体SQL 转实体类
JSON 结构多语言 Bean 类JSON 转 Java Bean
一个变量名7 种命名风格变量命名转换
JSON 数据XML 或反向JSON 转 XML
格式混乱的 JSON可读的缩进格式JSON 格式化校验

生成前建议先确认样本本身是合法 JSON —— 否则生成器拿到的是一段解析失败的内容,报错信息容易让人误以为是生成器的问题。

#常见问题

#生成出来的类型可以直接用吗?

可以,但可空字段必须手工核对。这是唯一一个生成器无法准确推断的信息:JSON 里某个字段的值恰好是 null 时,推断结果可能是 null 或 any,两者都不是理想的可选字段类型。做法是把它改成 string | null 这样的联合类型,再打开 TypeScript 的严格空值检查验证一遍。

#为什么 JSON 转 TS 后整数也变成了 number?

因为 JavaScript 运行时只有一个数字类型 number,底层是双精度浮点,没有 int 与 float 之分。把 JSON 的整数生成成 number 是符合运行时实际的选择。要注意的是绝对值超过 2^53 的整数在这个类型下会丢精度,这类字段(如雪花算法 ID)建议在接口层就序列化成字符串。

#空数组生成的类型为什么是 any[]?

因为空数组没有任何元素可供推断。这是信息缺失,不是工具缺陷 —— 你可以在样本里放一条有真实元素的记录再生成,或者手工把 any[] 改成具体类型。类型安全的项目里建议让样本尽量贴近真实数据,而不是用精简过的示例。

#数据库字段类型会完整映射到实体类吗?

长度与精度这类存储层约束不会带过去,例如 VARCHAR(255) 只会变成 string 或 String。是否可空会映射(取决于 NOT NULL),主键也会识别并加注解。日期时间类型在各语言间差异较大,生成后需要按项目规范统一,比如 Java 常用 LocalDateTime 而 TypeScript 用 string。

#命名转换能处理全大写的缩写词吗?

能拆开,但不同工具的约定不完全一致。像 HTTPServerURL 这类名称,有的工具拆成 http、server、url 三个词,有的会保留 HTTP 原样。批量改名之前先在小样本上确认拆分结果,避免全局替换后才发现风格不符合预期。

本文提到的工具

相关文章