基于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 }