Reputation: 85
I have a problem with Promises in Typescript. I'm trying to call Promise.all with an array of promises but instead, I get
No overload matches this call. The last overload gave the following error. Argument of type '(Promise | Promise)[]' is not assignable to parameter of type 'Iterable<boolean | PromiseLike>'. [...]
Below a simplified example of I'm referring to:
const promise1 = Promise.resolve(true); //promise1:Promise<boolean>
const promise2 = Promise.resolve('promise...'); //promise2:Promise<string>
const promises = [promise1, promise2];
Promise.all(promises); //Error here
However, the code below works as I'd assume.:
const promise1 = Promise.resolve(true);
const promise2 = Promise.resolve('promise...');
Promise.all([promise1, promise2]);
Seems like a bug to me, but I'm not sure. I've been looking through GitHub, searching this problem but I didn't find any matching. Or am I doing something wrong and there is a solution so you can overcome the problem. Obviously, I can't just write Promise.all([promise1, promise2]) in my primary code because the array of promises is dynamic.
I'm using typescript @3.9.6
.
Upvotes: 6
Views: 3414
Reputation: 15313
The problem has nothing to do with Promises per se, but rather with the way TypeScript infers the type of a tuple.
You can read more about the actual issue in this answer, but the gist of it is the following
const a = [1, "a", true] //<- (string | number | boolean)[], not [number, string, boolean]
The problem should be fixed with the introduction of variadic kinds in TS 4.0. For now, there are two ways to do what you want.
The first one is const assertions
const b = [1, "a", true] as const // <- [number, string, boolean]
And the second one is to use a utility function like the one posted in the answer I linked above.
In your specific case, the way Promise.all
is typed doesn't play well with how TS infers the type of promises
. This is easily fixed by having a proper tuple with one of the methods described above.
Upvotes: 8