Pls consider the following code (just as dummy example, as it is, for the purpose of the question):
class Image {
protected data: any;
public static setUp = async (_h: any): Promise<Image> => {
const me: Image = new Image();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}
class Image2 {
protected data: any;
public static setUp = async (_h: any): Promise<Image2> => {
const me: Image2 = new Image2();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}
class Image3 {
protected data: any;
public static setUp = async (_h: any): Promise<Image3> => {
const me: Image3 = new Image3();
me.data = await new Promise((resolve) => setTimeout(resolve, 500));
return me;
};
}
async function testing() {
await Promise.all([
Image.setUp({}), // 1st
Image2.setUp({}), // 2nd
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}), // from 11th we will get the following Problem reported
]);
}
The problem description
No overload matches this call.
The last overload gave the following error.
Argument of type '(Promise<Image> | Promise<Image2> | Promise<Image3>)[]' is not assignable to parameter of type 'Iterable<Image | PromiseLike<Image>>'.
The types returned by '[Symbol.iterator]().next(...)' are incompatible between these types.
Type 'IteratorResult<Promise<Image> | Promise<Image2> | Promise<Image3>, any>' is not assignable to type 'IteratorResult<Image | PromiseLike<Image>, any>'.
Type 'IteratorYieldResult<Promise<Image> | Promise<Image2> | Promise<Image3>>' is not assignable to type 'IteratorResult<Image | PromiseLike<Image>, any>'.
Type 'IteratorYieldResult<Promise<Image> | Promise<Image2> | Promise<Image3>>' is not assignable to type 'IteratorYieldResult<Image | PromiseLike<Image>>'.
Type 'Promise<Image> | Promise<Image2> | Promise<Image3>' is not assignable to type 'Image | PromiseLike<Image>'.
Type 'Promise<Image2>' is not assignable to type 'Image | PromiseLike<Image>'.
Type 'Promise<Image2>' is not assignable to type 'PromiseLike<Image>'.
Types of property 'then' are incompatible.
Type '<TResult1 = Image2, TResult2 = never>(onfulfilled?: ((value: Image2) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<...>) | null | undefined) => Promise<...>' is not assignable to type '<TResult1 = Image, TResult2 = never>(onfulfilled?: ((value: Image) => 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 'Image2' is not assignable to type 'Image'.
Property 'data' is protected but type 'Image2' is not a class derived from 'Image'.ts(2769)
lib.es2015.iterable.d.ts(226, 5): The last overload is declared here.
(property) Image3.setUp: (_h: any) => Promise<Image3>
I have noticed the following:
- the problem is not just related to number of elements in the array of Promises but also on the number of distinct types returned, in fact it won't report the problem if an array with length>10 will contain Promise that will return the same type
await Promise.all([
Image3.setUp({}), // 1st
Image3.setUp({}), // 2nd
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}), // NO ISSUES from here
Image3.setUp({}),
]);
Looks like the overload defined for Promise.all in type def are not managing mixed types after a length of ten elements.
A quick fix that I've found working is to nest Promise.all like this
async function testing() {
await Promise.all([
Promise.all([
Image.setUp({}), // 1st
Image2.setUp({}), // 2nd
]),
Promise.all([
Image2.setUp({}), // 3rd
Image3.setUp({}),
Image3.setUp({}), // 5th
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}),
Image3.setUp({}), //10th
Image3.setUp({}),
]),
]);
}
The above will extend the max of 10 elements returning mixed types.
The problem links to this line at interface PromiseConstructor into lib.es2015.iterable type def:
all<T>(values: Iterable<T | PromiseLike<T>>): Promise<T[]>;
I'd like to understand more the insight of this: where the type definition fails ? Is it something related to version lib.es2015 solved on following ones? Is it something related to PromiseLike? Why problem raises since 11th element?