我们知道 Promise.all 将以与请求的可迭代相同的顺序返回已解决的 Promise。
我试图了解如何为个人确定的决心输入正确的类型。 我正在使用 Axios 执行异步调用。
Promise.all([
<void, A>call an API a with response type A,
<void, B>call another API b with response type B,
<void, C>call another API c with response type C
]).then(([
Response aa of type A: ?,
Response bb of type B: ?,
Response cc of type C: ?
]) => {
});
所有响应均为
AxiosResponse<A | B | C>
类型。但是,如果我明确地将其设置为这一点,那么在读取其中一种响应类型中不存在的另一种响应类型中的属性时,我将面临问题。例如:如果属性 bb.test
不存在于 test
或 aa
中,编译器将抱怨 cc
。
以下是否可能,因为它明确说明了个人反应的类型?
]).then(([
Response aa of type A: AxiosResponse<A>,
Response bb of type B: AxiosResponse<B>,
Response cc of type C: AxiosResponse<C>
]) => {
注意:编译器会隐式地处理类型。
如果您像问题中那样将数组指定为文字,那么它应该可以工作。正如 Bergi 在评论中所写,
Promise.all
被声明为采用元组类型。
declare var a: Promise<A>;
declare var b: Promise<B>;
declare var c: Promise<C>;
Promise.all([a, b, c]).then(([a1, b1, c1]) => {
(a1);
//^? (parameter) a1: A
(b1);
//^? (parameter) b1: B
(c1);
//^? (parameter) c1: C
});
但是,TypeScript 会假设,如果您声明一个数组,它会尝试找到与数组的所有元素兼容的“最佳通用类型”。这会干扰您将数组解构为特定类型的能力。
let array = [a, b, c];
// ^? let array: (Promise<A> | Promise<B> | Promise<C>)[]
Promise.all([a, b, c]).then(([a1, b1, c1]) => {
(a1);
//^? (parameter) a1: (A | B | C)
(b1);
//^? (parameter) b1: (A | B | C)
(c1);
//^? (parameter) c1: (A | B | C)
});
要保留类型但仍使用数组,您必须使用const 断言
as const
指示 TypeScript 将其视为
tuple,就像在第一个示例中所做的那样。
let tuple = [a, b, c] as const;
// ^? let tuple: readonly [Promise<A>, Promise<B>, Promise<C>]
Promise.all(tuple).then(([a1, b1, c1]) => {
(a1);
//^? (parameter) a1: A
(b1);
//^? (parameter) b1: B
(c1);
//^? (parameter) c1: C
});
请参阅TypeScript 游乐场