Closed
Description
TypeScript Version: 4.0.2 (but also the version in the Playground)
Search Terms:
Promise.all type inference
Code
async function test() {
const promiseNumber = Promise.resolve(1);
const promiseVoid = async () => {}
await Promise.all([
promiseNumber,
...[promiseVoid()]
])
}
Expected behavior:
The Promise.all call should not throw any compile time errors due to type mismatches, since Promise.all simply returns the values of the array and waits until resolution if the value is a promise.
Actual behavior:
A compile time error is thrown:
No overload matches this call.
The last overload gave the following error.
Argument of type '(Promise<number> | Promise<void>)[]' is not assignable to parameter of type 'Iterable<number | PromiseLike<number>>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult<Promise<number> | Promise<void>, any>' is not assignable to type 'IteratorResult<number | PromiseLike<number>, any>'.
Type 'IteratorYieldResult<Promise<number> | Promise<void>>' is not assignable to type 'IteratorResult<number | PromiseLike<number>, any>'.
Type 'IteratorYieldResult<Promise<number> | Promise<void>>' is not assignable to type 'IteratorYieldResult<number | PromiseLike<number>>'.
Type 'Promise<number> | Promise<void>' is not assignable to type 'number | PromiseLike<number>'.
Type 'Promise<void>' is not assignable to type 'number | PromiseLike<number>'.
Type 'Promise<void>' is not assignable to type 'PromiseLike<number>'.
Types of property 'then' are incompatible.
Type '<TResult1 = void, TResult2 = never>(onfulfilled?: ((value: void) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined) => Promise<...>' is not assignable to type '<TResult1 = number, TResult2 = never>(onfulfilled?: ((value: number) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => PromiseLike<...>'.
Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
Types of parameters 'value' and 'value' are incompatible.
Type 'void' is not assignable to type 'number'.(2769)
Workaround:
Setting the generic type argument of Promise.all to void | number
works, but this is a step backwards after TypeScript added better Promise.all inference and it should know that the first argument that will be returned from the call will be a number:
// Workaround which throws no errors:
async function test() {
const promiseNumber = Promise.resolve(1);
const promiseVoid = async () => {}
await Promise.all<number | void>([
promiseNumber,
...[promiseVoid()]
])
}
Playground Link:
Related Issues: