Advertisements
Given two promises – one that needs to be executed every time and one that needs to be executed only if a condition is met – that I want to execute asynchronously, how do I ensure that return type of Promise.all
for each value is correct?
Here’s an implementation that I thought should work:
type Promises = [Promise<string>, Promise<number>?]
const promises: Promises = [Promise.resolve('Lorem')]
if (someCondition) {
promises.push(Promise.resolve(1))
}
// 'resolvedString' should be string
// 'resolvedNumber' should be number | undefined
const [resolvedString, resolvedNumber] = await Promise.all(promises)
but there are two issues with this code:
-
Value of
resolvedNumber
isnumber
and notnumber | undefined
according to VSCode -
TS doesn’t compile because of following error:
The last overload gave the following error.
Argument of type 'Promises' is not assignable to parameter of type 'Iterable<string | PromiseLike<string>>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult<Promise<string> | Promise<number>, any>' is not assignable to type 'IteratorResult<string | PromiseLike<string>, any>'.
Type 'IteratorYieldResult<Promise<string> | Promise<number>>' is not assignable to type 'IteratorResult<string | PromiseLike<string>, any>'.
Type 'IteratorYieldResult<Promise<string> | Promise<number>>' is not assignable to type 'IteratorYieldResult<string | PromiseLike<string>>'.
Type 'Promise<string> | Promise<number>' is not assignable to type 'string | PromiseLike<string>'.
Type 'Promise<number>' is not assignable to type 'string | PromiseLike<string>'.
Type 'Promise<number>' is not assignable to type 'PromiseLike<string>'.
Types of property 'then' are incompatible.
Type '<TResult1 = number, TResult2 = never>(onfulfilled?: (value: number) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => Promise<...>' is not assignable to type '<TResult1 = string, TResult2 = never>(onfulfilled?: (value: string) => TResult1 | PromiseLike<TResult1>, onrejected?: (reason: any) => TResult2 | PromiseLike<TResult2>) => PromiseLike<...>'.
Types of parameters 'onfulfilled' and 'onfulfilled' are incompatible.
Types of parameters 'value' and 'value' are incompatible.
Type 'number' is not assignable to type 'string'.
93 const [resolvedString, resolvedNumber] = await Promise.all(promises)
TypeScript version is 4.3.5
>Solution :
This is a bug/feature that has been fixed on TS 4.5.