Repository navigation
Wrong return type inference in a generic function using Promise.all #37664
Description
Can I resolve this problem below without the awaited keyword? how can I infer return type without having to use as unknown as R[] and providing a hardcoded type each time?
// Promise.all(this.fork) take a T1[] where T1 is a Promise<number>
// and return a Promise<T2[]> where T2 is a number
// therefore T1 and T2 are not both «T»TypeScript Version: 3.9.0-dev.20200326
Search Terms:
Promise.all
promise.all generic
generic awaited
awaied
Code
Code as text below -- Click to enlarge image -- #Pop N' Lock Theme by Luxcium ✨
export class MyMaybeList<T = any> {
private constructor(values: T[]) {
this.values = values;
}
private values: T[];
// get =======================================================-| fork() |-====
public get fork(): T[] {
return this.values != null ? this.values.slice() : [].slice();
}
// public =====================================================-| map() |-====
public map<R = any>(
fn: (val: T, index: number, array: T[]) => R
): MyMaybeList<R> {
return MyMaybeList.of(...this.values.map(fn));
}
// static ======================================================-| of() |-====
public static of<TVal>(...val: TVal[]): MyMaybeList<TVal> {
if (val == null || !val.length) return new MyMaybeList<TVal>([]);
return new MyMaybeList<TVal>([...val]);
}
// async =====================================================-| will() |-====
public async will /* <R> */() /* : Promise<MyMaybeList<R>> */ {
// Promise.all(this.fork) take a T1[] where T1 is Promise<number>
// and return a Promise<T2[]> where T2 is a number
// therefore T1 and T2 are not both «T»
console.log(this.fork);
const willThen = Promise.all(this.fork);
const thenWill = await willThen;
return MyMaybeList.of(...thenWill);
}
}Code as text below -- Click to enlarge image -- #Pop N' Lock Theme by Luxcium ✨
const oneToTen = MyMaybeList.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
const powersOneToTen = oneToTen.map(async val => val * val);
// "log->" powersOneToTen: MyMaybeList<Promise<number>>
console.log(powersOneToTen);
// "log->" awaitedList: MyMaybeList<Promise<number>>
// instead of a -> MyMaybeList { Promise<number> }
// in fact is a -> Promise { MyMaybeList<number> }
const awaitedPowersOneToTen = powersOneToTen.will /* <unnknow> */();
awaitedPowersOneToTen.then(awaitedList => console.log(awaitedList));
// Promise { <pending> } will resolve into ->
console.log(awaitedPowersOneToTen);Now that #37610 has reverted the awaited type I don't know what to do I have provided an example above but my real-life situation is as follow :
I was relying on this solution because I have a
Promise<MaybeList<Promise<ISymbolSearchResult[]>>>
where MaybeList is an array abstraction so I am using promise.all to remove the inner Promise I don't know what to do now to avoid using «as unknown as MaybeList<ISymbolSearchResult[]>» inside of my async function (which should be returning thePromise<MaybeList<ISymbolSearchResult[]>>instead of thePromise<MaybeList<Promise<ISymbolSearchResult[]>>>) *Note that I have an array ofISymbolSearchResultinside an arrayLike of type MaybeList so, in this case, an array inside of an array
Actual behavior:
Promise<MyMaybeList<Promise<number>>> (as in 3.9.0-dev.20200326)
Expected behavior:
Promise<MyMaybeList<number>> (as in 3.9.0-dev.20200324)
Related Issues:
#37610, #37526, #33055, #30551, #35998, #37534, #37115, #34925
maybe also:
#9998, #33707, #36232, #35136, #33562, #34883, #31394
as discussed in TypeScript 3.9 Iteration Plan #37198



Activity
[-]Can not get correct return type inference when using Promise.all in a generic function[/-][+]Wrong return type inference in a generic function when using Promise.all [/+][-]Wrong return type inference in a generic function when using Promise.all [/-][+]Wrong return type inference in a generic function using Promise.all [/+]adrienboulle commentedon Apr 8, 2020
If it can help i have this example
Here the thing that break type inferring is the fact that one of the promises has unknown type even if its return value is not used
Luxcium commentedon Apr 9, 2020
**I am sorry Adrien Boullé (@adrienboulle) I am not sure what I should be looking for in your example you mention I think the line 13 where
getNumbersB()is not used but I don't see the problem ... **At this moment I am still using
3.9.0-dev.20200324because for some random reason I had that problem on 03-23 got that fix by chance on the 24th and it got reverted the day after ...Luxcium commentedon Apr 9, 2020
ok (OOPS!) I forgot to install the
typescript@latest(3.8.3) and I think thetypescript@nextis not breaking (3.9.0-dev.20200408) so I can upgrade from3.9.0-dev.20200324yes I have « 🍒» inside of my error messages LoL 😹
adrienboulle commentedon Apr 9, 2020
haha i can't blame you tu add some joy on your code!
So if i understand correctly, 3.9.0 fixes the issue ?
RyanCavanaugh commentedon Apr 20, 2020
I'm not really sure what's going on here; we need a concise problem description to work from
Luxcium commentedon Apr 21, 2020
Luxcium commentedon Apr 21, 2020
The TypeScript playground site was not working correctly for me when I have first opened this issue it is now working ...
With: 3.9.0-dev.20200324 the following code
awaitedPowersOneToTen.then(awaitedList => console.log(awaitedList));when I mouse overawaitedListit is aMyMaybeList<number>But with: 3.9.0-dev.20200420 the following code
awaitedPowersOneToTen.then(awaitedList => console.log(awaitedList));when I mouse overawaitedListit is aMyMaybeList<Promise<number>>Luxcium commentedon Apr 21, 2020
I am using
Promise.allon something like an array or a list (MyMaybeList) and I want to infer the type without explicitly passing it (in a generic) ...Promise.allshould remove thePromiseinside of my list so I can getMyMaybeList<number>a list of "numbers" instead of gettingMyMaybeList<Promise<number>>a list of "Promises of a number" which is the type that I have before usingPromise.allLuxcium commentedon May 4, 2020
I got this error message and don't know what I should do ...
error(TS2345): Argument of type 'awaited T' is not assignable to parameter of type 'T'.
'T' could be instantiated with an arbitrary type which could be unrelated to 'awaited T'.
TypeScript code:
lib/functional/promise-or-not.tsOutput:
tsc Version 3.9.0-dev.20200324Playground 3.9.0-dev.20200324
Playground Nightly
Playground 3.8.3
Luxcium commentedon May 4, 2020
Due to different other problems in my code when using other TS version I am stuck using
Version 3.9.0-dev.20200324In regard to the problem described above in my previous comment I could, meanwhile, do:
return promise.then(t => funct((t as any) as T));or do:
return promise.then(t => funct((t as unknown) as T));I am not sure the difference between using
unknownoranyin this particular example ...This is when using
Version 4.0.0-dev.20200504other parts of code are not shown here, the problem is detailed above in this current GitHub issue #37664jakebailey commentedon Jan 24, 2022
After 4.5, I don't think that this is a problem anymore thanks to the
Awaitedchanges; I'm going to close this, but can reopen if I'm mistaken.Luxcium commentedon Jan 28, 2022
It's not a problem anymore indeed !!! thanks to the TS Team to have made it possible... and sorry for the long delay but at least it is now resolved for me !!!