你可能没用好 typescript

共 3074字,需浏览 7分钟

 ·

2023-06-26 13:27

前言

最近在社区看到很多类似 typescript 不适合写业务的言论,我觉得这些言论都是基于一些误解,用好 typescript 对业务代码的健壮性和可维护性是有很大帮助的,本文就来聊聊如何用好 typescript

为什么你会觉得 typescript 不适合写业务

我们就用后台业务最常见的 Form,Table 页面来聊聊,你为什么会觉得 typescript 不适合写业务

ca54a1cc32c5689fcf291e24954aaae6.webpimage.png

首先,对于这个常见的页面,我们所有的查询操作都是基于列表的查询接口。而列表查询接口所有的参数,不管是 page, size 还是各种 filter 都会最终影响你表格数据的展示。

所以对于这类页面最常见的一个操作就是把这些参数都放到 你的 deps 中,我们只需要改变 deps 中的值,就会自动触发 useEffect 请求数据。当然,如果你使用了 swr react-query 这类请求库,deps 就应该换成 key

下面我用 swr 一个常见的列表接口来举例。

      
      import useSWR from 'swr';

// swr 传了范型这里 axios 的输入输出可以不用写,但是为了方便理解以及照顾不用 swr 的朋友,我还是写了
// 不用 axios 的朋友换成自己项目的请求就好了
const fetcher = ([url, params]: [url: string, params: ListParams]) => {
  return req_get(url, params).then((res) => res.data);
};

function useList(params: ListParams) {
  const {dataisLoading} = useSWR<ListOutput>(['/api/list', params], fetcher);
  return {
    datadata?.list,
    countdata?.count,
    isLoading,
  };
}

可以看到,相比 javascript ,需要额外做的工作其实就是定义参数类型 ListParams 和接口返回的类型 ListOutPut。(ListParams 也是我们需要定义的 state 的类型)

只要定义好了输入和输出的类型,typescript 就会帮你做好类型检查,并做好代码提示。这样你就不用担心参数传错了,或者接口返回的数据类型不对了, 也不用担心 data 为空的时候,出现以下常见的错误提示

      
      Cannot read properties of undefined (reading 'xxx')

很多人觉得 typescript 不适合写业务,我想是因为他们觉得定义类型,特别是一些复杂的类型是一件很麻烦的事情。

如果体验过 tRPC , 或者 graphql-codegen 的话,你就会发现,其实这些类型都是可以复用的。我们的后台一般都是用强类型语言编写的。他们在写接口的时候,其实已经定义好了这些类型,我们只需要把这些类型拿过来就好了。

但是我们大多数人的项目前后端都不是一个仓库,也不是 graphql , 那么我们怎么拿到这些类型呢?

OpenAPI

OpenAPI规范(以前称为Swagger规范)是一种机器可读的接口定义语言规范,用于描述,生成,使用和可视化Web服务。它以前是Swagger框架的一部分,在2016年成为一个独立的项目,由Linux基金会的一个开源协作项目OpenAPI Initiative监督。

如果你的项目遵循 OpenAPI 规范,后台会给你一个 swagger 文档。那么恭喜你,你可以直接用 swagger 生成的 typescript 类型。

如果你在 github 上用 openapi , codegen , swagger 之类的关键词搜索,你会发现有很多开源的工具可以帮你生成 typescript 类型。

甚至有很多项目会直接帮你生成接口,但是我觉得自动生成接口这种东西如果你自己用 node 写一个类似的工具会更加符合你的业务需求。我们需要的仅仅是开箱即用,生成类型

生成类型

我就用我们项目中常用的 openapi-typescript 来举例,选择他的原因纯粹是因为够简单,你可以自由选择你要的工具。首先安装

      
      // 选择 5.4.1 版本,原因后面会说。使用 npm 的自行翻译一下
yarn add -D openapi-typescript@5.4.1

然后在 package.json 中配置

      
      //没有 prettier 的话,不要 --c .prettierrc.js
{
  "scripts": {
    "codegen""npx openapi-typescript 这里你填你swagger.json的地址 --c .prettierrc.js --make-paths-enum   --output ./src/ApiInterface.ts",
  }
}
// 这里的 --make-paths-enum 是为了生成路径的枚举
// 最新版本去掉了这个功能,我觉得这个功能很实用,所以我选择了 5.4.1 版本

然后我们每次运行 yarn codegen 就可以生成 ApiInterface.ts 文件了。

以我们的一个真实项目为例子,首先我们来看生成的路径枚举dbab095345738a3fb4ebd51c5a00ab72.webp

有了路径枚举我们就不需要自己写路径了,直接用枚举就好了,这样就不会出现路径写错的问题了。

e6ec43b68eecf29b9008073cc8c0873c.webp

hight.gif

然后我们来看看生成的类型f4c5de174e1054123cfbf9b080e69e88.webp

可以看到我们主要想要的都是 components 下的 schemas 类型。像上个 gif 一样,我们可以定义一个类型

      
      import { type components } from '@/ApiInterface'

export type ApiInterface = components['schemas']

这样,我们就不再需要自己来手动定义输入输出的类型了,就可以愉快的回车到底了

fc61aec7f36240ecc6c920ed6e9a42e5.webp

code.gif

总结

这种方案虽然不如 tRPC 那样直接复用一个类型,后台只要更改类型,前端就会报错。但是 tRPC 迁移的成本是很高的,而且很多公司的后台都不是用 typescript 写的,但是很多公司都会遵循 OpenAPI 规范。

如果后台改了接口,只需要运行一下 yarn codegen,编辑器就会自动给你提示哪些地方需要修改,你就会觉得 typescript 写业务也是一件很愉快的事情了。

最后,希望本文能对你有所帮助,以上。

浏览 43
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报