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

相关推荐
花花鱼9 分钟前
spring boot lunar 农历的三方库引用,获取日期的农历值
java·前端·spring boot
fly spider17 分钟前
1.短信登录
前端·firefox
前端小巷子1 小时前
CSS渲染性能优化
前端·css·面试·性能优化
苦学编程的谢2 小时前
计算机是如何工作的
服务器·前端·javascript
蓉妹妹2 小时前
React+Taro选择日期组件封装
前端·react.js·前端框架
风口上的吱吱鼠2 小时前
记录 ubuntu 安装中文语言出现 software database is broken
linux·服务器·前端
whltaoin2 小时前
前端弹性布局:用Flexbox构建现代网页的魔法指南
前端·弹性布局
GISer_Jing3 小时前
前端工程化和性能优化问题详解
前端·性能优化
学渣y3 小时前
React文档-State数据扁平化
前端·javascript·react.js
njsgcs3 小时前
画立方体软件开发笔记 js three 投影 参数建模 旋转相机 @tarikjabiri/dxf导出dxf
前端·javascript·笔记