请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

axios函数的返回值类型

老师的代码是这么写的:

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,你是没法为它指定类型的。

0 回复 有任何疑惑可以回复我~
  • 提问者 慕莱坞0998854 #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-07-03 02:35:32
  • 提问者 慕莱坞0998854 #2
    老师我还想再多问一句,那Promise类是不是只有Promise<T>这样的,代表Promise最后resolve之后的类型,没有Promise最后reject之后的类型
    回复 有任何疑惑可以回复我~ 2020-07-03 02:38:36
  • ustbhuangyi 回复 提问者 慕莱坞0998854 #3
    是的啊
    回复 有任何疑惑可以回复我~ 2020-07-03 09:37:08
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信