基于Typescript泛型简单封装axios

因为使用axios时 ,我们大多数时候处理响应都是只提取res.data.data里面的数据,所以每次都得写两层data过于繁琐,我们在响应拦截器中修改了返回值为 res.data,此时会导致res的类型提示不正确,还是原来的结构,所以我们需要重新封装请求工具,使其符合类型提示。

instance 是axios创建的一个实例

初版:

这里我们定义了一个函数request,给他设置了函数泛型T,并设置三个参数的类型,然后在回调函数中,设置返回类型(需要符合后端传回来的结构),并根据axios的封装得知,axios的泛型默认会把泛型的第一个类型包裹进第二个泛型:

使其符合如下结构:

这就是导致我们类型提示还是原来的结构的原因,所以 我们需要将第二个泛型传入我们想要的结构(这里如果传两个类型,第一个就失效了,因为第一个就是提供参数被第二个包裹进axios的默认响应数据结构的,所以这里第一个参数传什么其实没有区别),此时类型结构已经正确了,再补充上通过method对传入数据的对象名是data还是params的判断。

第二稿,个人封装版:

因为初版使用是直接传url、method、data的值,显得非常抽象,并且不符合我们原来使用axios的习惯,代码可读性极低,所以我想试着将axios封装为我常用的写法如下:

先设置一个参数类型:

根据新的参数类型修改封装的工具,完整效果:

这里需要提的点:默认method判断修改至return前面,以防未定义的报错

新增对delete和put的判断(这里只考虑常用的 get post delete put 请求)

此时已经完成了,使用方式和我想要的一致:

完整代码:

// 请求工具函数
interface paramsType {
  url: string
  method?: Method
  data?: object
}
const request = <T>(res_data: paramsType) => {
  // 根据后台设置数据的类型
  type Data<T> = {
    code: number
    message: string
    data: T
  }
  // 设置默认get (如果没传默认给个get)
  res_data.method = res_data.method ? res_data.method : 'get'

  return instance.request<T, Data<T>>({
    url: res_data.url,
    method: res_data.method,
  // 如果为get和delete使用params,否则使用data
    [res_data.method.toLowerCase() === ('get' || 'delete')
      ? 'params'
      : 'data']: res_data.data
  })
}

export { request }
posted @ 2023-03-03 20:53  Tdom  阅读(663)  评论(0编辑  收藏  举报