很遗憾,Axios.all 的声明不是很好。它的输入方式不能传入元组。
export interface AxiosStatic extends AxiosInstance {
all<T>(values: (T | Promise<T>)[]): Promise<T[]>;
}
参数必须是单一类型的数组T。 Typescript 不会推断 T 的联合,也无法推断出预期数组的元组。
我们可以看看Promise.all 是如何输入的(它确实支持元组)
all<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>;
// ...
all<T1, T2, T3, T4>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike <T4>]): Promise<[T1, T2, T3, T4]>;
all<T1, T2, T3>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>;
all<T1, T2>(values: [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>;
all<T>(values: (T | PromiseLike<T>)[]): Promise<T[]>;
我们可以看到他们使用了大量的重载来支持元组。
如果 Axios 承诺符合规范,您可以尝试使用 Promise.all。这些类型可以解决,但我自己没有测试过运行时行为。
const getAll = () => Promise.all([getO1(), getO2()]) //() => Promise<[AxiosResponse<Request<O1>>, AxiosResponse<Request<O2>>]>
或者你可以坚持使用 axios 版本并使用一些类型断言:
const getAll = () => Axios.all<{}>([getO1(), getO2()]) as unknown as AxiosPromise<[Request<O1>, Request<O2>]>
只是一个有趣的说明,在 3.1 中,我们将能够在没有 10 个重载的情况下键入 all:
type PromiseResult<T> = T extends AxiosPromise<infer R>? R: T
type ArrayPromiseResult<T extends (any | AxiosPromise<any>)[]> = { [P in keyof T]: PromiseResult<T[P]> }
declare function all<T extends [] | (any | AxiosPromise<any>)[]>(values: T): AxiosPromise<ArrayPromiseResult<T>>
let result = all([getO1(),getO2()]) // result is AxiosPromise<[Request<O1>, Request<O2>]>