axios函数的返回值类型
来源:7-5 -1 响应数据支持泛型- 需求分析+ 接口添加泛型参数+ demo 编写

慕莱坞0998854
2020-07-02
老师的代码是这么写的:
function getUser<T=any>(){
return axios<ResponseData<T>>('/extend/user').then(res=>res.data).catch(err=>console.error(err))
}
此时把鼠标放在res上,发现res可以被显示为AxiosResponse<ResponseData<T>>
,我想了一下,因该是下面的代码起的作用
export interface AxiosInstance extends Axios {
<T=any>(config: AxiosRequestConfig): AxiosPromise<T>
<T=any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
}
但是此时把鼠标放在err上,却发现err是any类型。我不明白的是,为什么这里只写了AxiosPromise,却没有写reject时情况,我尝试着改成下面的写法
export interface AxiosInstance extends Axios {
<T=any>(config: AxiosRequestConfig): AxiosPromise<T> | IAxiosError
<T=any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T> | IAxiosError
}
但是这样又会报错,因为联合类型只能调用两个类型共有的方法,所以下面的代码会报错
// property then doesn't exist on tyepe IAxiosError
function getUser<T=any>(){
return axios<ResponseData<T>>('/extend/user').then(res=>res.data).catch(err=>console.error(err))
}
再回想一下我们以前定义的AxiosError类是怎么使用的
axios({
method: 'get',
url: '/error/timeout',
timeout: 2000
}).then((res) => {
console.log(res)
}).catch((e:IAxiosError) => {
console.log(e.message)
console.log(e.config)
console.log(e.code)
console.log(e.request)
console.log(e.isAxiosError)
})
居然是手动指定e是IAxiosError类的。
又什么办法可以统一下吗?
1回答
-
你这块理解错了,首先
export interface AxiosInstance extends Axios {
<T=any>(config: AxiosRequestConfig): AxiosPromise<T>
<T=any>(url: string, config?: AxiosRequestConfig): AxiosPromise<T>
}
这个表面了 axios 的方法返回值类型是 AxiosPromise<T>,它是一个继承 Promise 的类型
export interface AxiosPromise<T = any> extends Promise<AxiosResponse<T>> {}
你可以看一下 lib.es5.d.ts 中对于 Promise 类型的定义:
interface Promise<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2>;
/**
* Attaches a callback for only the rejection of the Promise.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of the callback.
*/
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult>;
}
可以看到,then 对应的 onfufilled 函数的第一个参数 value 类型就是 T,对应到 AxiosPromise<T>,就是 AxiosResponse<T>,对应到这个示例,就是 AxiosResponse<ResponseData<T>>。
但你去看 catch 函数,它对应的 onrejected 函数的第一个参数 reason 就是 any,你是没法为它指定类型的。032020-07-03
相似问题