Repository navigation
Incorrect type inference of Promise.all when spreading Promise arrays #40330
Description
Activity
- addedNeeds InvestigationThis issue needs a team member to investigate its status.This issue needs a team member to investigate its status.
on Sep 9, 2020 timsuchanek commented
on Oct 29, 2020 ContributorMore actionsI have this issue as well.
It came up in an issue in Prisma ClientIt happens in the following code:
declare function a(): Promise<number> declare function b(): Promise<string> async function main() { const x = await Promise.all( [ ...[2].map(() => a()), b() ] ) }
Could variadic tuples maybe tackle this problem?
- addedRescheduledThis issue was previously scheduled to an earlier milestoneThis issue was previously scheduled to an earlier milestone
on Dec 11, 2020 I opened this same issue: #43157
But closed it 10 minutes later when I double-checked the playground and realized it wasn't specific to 4.2.Is my error related to this issue?
"typescript": "^4.2.4"Note: All those
get...()functions returnPromise<SomeType>.With a single promise, it's all fine. But as soon as I pass more than one promise to the array, it shows the following error:
Full error content:
No overload matches this call. The last overload gave the following error. Argument of type '(Promise<AdminFlags> | Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>)[]' is not assignable to parameter of type 'Iterable<AdminFlags | PromiseLike<AdminFlags>>'. The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types. Type 'IteratorResult<Promise<AdminFlags> | Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>, any>' is not assignable to type 'IteratorResult<AdminFlags | PromiseLike<AdminFlags>, any>'. Type 'IteratorYieldResult<Promise<AdminFlags> | Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>>' is not assignable to type 'IteratorResult<AdminFlags | PromiseLike<AdminFlags>, any>'. Type 'IteratorYieldResult<Promise<AdminFlags> | Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>>' is not assignable to type 'IteratorYieldResult<AdminFlags | PromiseLike<AdminFlags>>'. Type 'Promise<AdminFlags> | Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>' is not assignable to type 'AdminFlags | PromiseLike<AdminFlags>'. Type 'Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>' is not assignable to type 'AdminFlags | PromiseLike<AdminFlags>'. Type 'Promise<{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }>' is not assignable to type 'PromiseLike<AdminFlags>'. Types of property 'then' are incompatible. Type '<TResult1 = { all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }, TResult2 = never>(onfulfilled?: ((value: { all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }) => TResult1 | PromiseLike<...>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLik...' is not assignable to type '<TResult1 = AdminFlags, TResult2 = never>(onfulfilled?: ((value: AdminFlags) => 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 '{ all: BrandItem[]; allValues: string[]; byValue: Record<string, BrandItem>; }' is missing the following properties from type 'AdminFlags': showPrices, showAdsts(2769) lib.es2015.iterable.d.ts(226, 5): The last overload is declared here.What could this be?
Reacted by Brian Frichette4 remaining items
Seems to be resolved now on 4.6.4
You can use it this way, I tested it and it works
const promises: Promise<number, string>[] = [promiseNumber, promiseString]; const res = await Promise.all(promises);
You dont want
<number, void>, what you want is that types come from their own.But it seems to be fixed :)Reacted by Trần Minh QuangMаартен - Maarten (@maapteh) Sorry for this, i tried it with types
<string, number>. Yah, it seems to be fixed, so i solved my problem this way :DReacted by Mаартен - Maarten- addedFix AvailableA PR has been opened for this issueA PR has been opened for this issue
on Mar 4, 2023


TypeScript Version: 4.0.2 (but also the version in the Playground)
Search Terms:
Promise.all type inference
Code
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:
Workaround:
Setting the generic type argument of Promise.all to
void | numberworks, 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:Playground Link:
https://www.typescriptlang.org/play?#code/IYZwngdgxgBAZgV2gFwJYHsI2QUxMgCgEoYBvAKHJmpik3xgAcAndAW1RBwDkE2AjHMxgBeGAAVWHLgDpmedABsAbjgIBGIgG4qNOhAYt2nHADV0qACaiYoSLGKiAfGQC+lGrYDuwVMglSJjLAiooEANq6ntRG0jx8gswANFHRMunhsSbmVsQAuql5ROSuQA
Related Issues: