看我如何破解api接口文档定义空白, 还不想手动写接口TS类型定义的困局

背景

最近接手了一个项目,虽然号称是用Typescript写的,可是我用ESLint检测了一下

json 复制代码
"scripts": {
  "code:fix": "eslint --fix \"src/**/*.{ts,tsx}\""
}
bash 复制代码
yarn code:fix

发现检测出来的代码质量问题,基本上全是TS类型使用any定义。点开每个提示警告的文件看了一下,估算TS类型定义使用any定义占比在98%以上,真是有名无实呀。看下图 公司原本就有对这个项目的重构计划,一直因为各种事情耽搁下来。现在看到这种情况,立刻启动了重构计划。而我的任务就是填充项目缺失的ts类型定义。

发现问题

在补充ts类型定义时发现,有很大一部分缺失的ts类型定义是接口定义。之前使用过yapi-to-typescript工具根据YApi的接口定义生成 TypeScript接口类型定义。原本心里一阵窃喜,可以轻车熟路的完成这项工作任务。但随后问了一下后端,他们接口文档管理使用的是apifox,而yapi-to-typescript只支持YApi或Swagger。看来原来的经验失效了。只能硬着头皮手动补全接口类型定义。却又发现apifox上的接口定义写的不规范,之前的后端开发偷懒,许多接口没写请求响应字段说明。如下图所示,空空如也。真是一波二折,事情做起来不顺畅。

解决问题

面对遇到的困难,我觉得社区应该有解决方案。抱着试试看的心态,带着问题上网搜了一下,果然有收获。找到了一个 在线JSON转typescript工具。可将json数据转换成TS类型定义。如果这个json数据是接口返回数据,目的不就达到了。虽然apifox上许多接口响应数据定义说明一片空白,可我可以直接访问线上的项目,在浏览器调试窗口,查看获取接口响应数据。 刚高兴了没几分钟,很快又发现,由于自己对刚接手的项目不熟,不知道该怎样操作,才能走到ts类型定义缺失的特定接口调用流程,获取到接口响应数据。遇到这种情况,自然而然的想到了postman这类工具。可以查看项目代码中调用接口的URL和参数,在postman这类工具中,手动发起接口调用请求,获取接口响应数据。这两个工具结合起来,就能丝滑柔顺的解决我面临的问题。

我之前已经安装过一个类似postman的浏览器扩展,如下图所示

用此工具,根据项目代码中调用的接口URL和参数,手动发起网络请求,就能方便的获取到ts类型定义缺失的接口响应数据。

把接口响应数据从浏览器中复制出来,粘贴到在线json转ts工具网站,点击json数据下方的复制按钮,就能获取期望的ts接口类型数据定义。稍微改改就能投入使用。经过思维的跳跃连接,困难迎刃而解。

探究原理

比较好奇,在线JSON转typescript工具网站,是怎么将json对象转换成ts类型定义的,感觉应该不难。可以用最质朴的思路,自己写一个。大致思路是ts类型用typeof判断,对象的键值还是对象的话,继续递归,再加上缩进美化功能,就写出了一个基础版本。

js 复制代码
function jsonToTs(json, indent = 0) {
  if (typeof json !== 'object' || json === null) return 'any';

  if (Array.isArray(json)) {
    if (json.length === 0) return 'any[]';
    return `${jsonToTs(json[0], indent)}[]`;
  }

  const indentation = '  '.repeat(indent);
  const lines = Object.entries(json).map(([key, value]) => {
    let type;
    switch (typeof value) {
      case 'string':
        type = 'string';
        break;
      case 'number':
        type = 'number';
        break;
      case 'boolean':
        type = 'boolean';
        break;
      case 'object':
        type = jsonToTs(value, indent + 1);
        break;
      default:
        type = 'any';
    }
    return `${indentation}  ${key}: ${type};`;
  });

  return `{\n${lines.join('\n')}\n${indentation}}`;
}

// 示例
const json = {
  name: 'Tom',
  age: 25,
  likes: ['code'],
  profile: {
    school: 'XYZ'
  }
};

console.log('type Data = ' + jsonToTs(json));

测试了一下,输出符合预期

ts 复制代码
type Data = {
  name: string;
  age: number;
  likes: string[];
  profile: {
    school: string;
  };
};

不过仍有改进的地方:1.无法生成取值是多个类型的情况。2.无法生成可选项。今天先到这里,后续有热情了再继续完善。

相关推荐
Charlie_lll几秒前
学习Three.js–雪花
前端·three.js
onebyte8bits17 分钟前
前端国际化(i18n)体系设计与工程化落地
前端·国际化·i18n·工程化
C澒26 分钟前
前端分层架构实战:DDD 与 Clean Architecture 在大型业务系统中的落地路径与项目实践
前端·架构·系统架构·前端框架
BestSongC30 分钟前
行人摔倒检测系统 - 前端文档(1)
前端·人工智能·目标检测
0思必得01 小时前
[Web自动化] Selenium处理滚动条
前端·爬虫·python·selenium·自动化
Misnice1 小时前
Webpack、Vite、Rsbuild区别
前端·webpack·node.js
青茶3601 小时前
php怎么实现订单接口状态轮询(二)
前端·php·接口
大橙子额2 小时前
【解决报错】Cannot assign to read only property ‘exports‘ of object ‘#<Object>‘
前端·javascript·vue.js
爱喝白开水a3 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
董世昌413 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6