You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Contextual generic return type of an async function includes union members from the context that it shouldn'tΒ #47682
declareclassStateMachine<T>{onDone: (a: T)=>void;}declarefunctioncreateMachine<T>(implementations: {services: Record<string,()=>Promise<T>|StateMachine<T>>;}): void;// this is close to my original issue found in the real-world in XStatecreateMachine<{count: number}>({services: {test: async()=>Promise.reject("some err"),asynctest2(){returnPromise.reject("some err");},},});// this is an additional test case I've figured out that behaves in a similar way.functionfn1(): ()=>Promise<{count: number}>|StateMachine<{count: number}>{returnasync()=>Promise.reject('some err')}
π Actual behavior
Both tests fail to compile and the reported error looks bizzare(-ish):
Type '() => Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type '() => Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }> | StateMachine<{ count: number; }>'.
Type 'Promise<{ count: number; } | StateMachine<{ count: number; }>>' is not assignable to type 'Promise<{ count: number; }>'
For some reason, the return type here didn't narrow the contextual union to include only Promise(-like?) members and dragged the whole Awaited<Union> to the computed contextual type. And this has caused an assignability problem.
Note that this "only" happens with Promise.reject, it's not reproducible with Promise.resolve and other similar types. My guess is that it's because Promise.reject contains a generic only at the return type position and this is what makes this issue manifest somehow.
π Expected behavior
No error should be reported because this is valid code and it looks like sufficient information has been provided in the context for this to be narrowed down properly~.
While looking into this problem I've poked around the internals of TS and figured out that this might be a potential fix for this issue: #47683
Activity
JoostK commentedon Jul 4, 2022
This is also causing errors in Angular codebases as reported in angular/angular#46697.
Minimum example:
Playground link (nightly)
Andarist commentedon Jul 5, 2022
Joost Koehoorn (@JoostK) I've confirmed that my PR fixes your case too and pushed out your minimal repro as an additional test case there: ce8c012