看我如何破解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.无法生成可选项。今天先到这里,后续有热情了再继续完善。

相关推荐
枫super4 分钟前
Day-03 前端 Web-Vue & Axios 基础
前端·javascript·vue.js
程序猿chen37 分钟前
Vue.js组件安全工程化演进:从防御体系构建到安全性能融合
前端·vue.js·安全·面试·前端框架·跳槽·安全架构
你也来冲浪吗1 小时前
MD编辑器用法讲解
前端
小小小小宇1 小时前
十万字总结所有React hooks(含简单原理)
前端
MariaH1 小时前
MySQL数据库DQL
前端
Enjoy10241 小时前
v8垃圾回收机制
前端
Georgewu1 小时前
【HarmonyOS 5】敏感信息本地存储详解
前端·harmonyos
_Le_1 小时前
css 小师系列:一种新的影响样式优先级的方式😍
前端·css
wordbaby1 小时前
从前端视角看 MCP:解锁 LLM 工具调用与结构化交互
前端
CodePencil1 小时前
CSS专题之CSS单位
前端·css