I have a LazyPromise
object with all
method. It works like Promise.all
but the promises start the call not on initialization, eg.:
// It started executing as soon as it was declared
const p1 = Promise.all([Promise.resolve(1), Promise.resolve('foo')])
// It started executing only when `p2.then()` is called
const p2 = LazyPromise.all([() => Promise.resolve(1), () => Promise.resolve('foo')])
this is the implementation
class LazyPromise {
static all(lazies: Array<() => Promise<any>>){
return Promise.all(lazies.map(lazy => lazy()));
}
}
usage
const result = LazyPromise.all([() => Promise.resolve(1), () => Promise.resolve('foo')]).then(result => console.log(result))
I want make the result with correct types.
Now result is a any[]
I want: [number, string]
How infer the correct result types?
2
Answers
Respond my self after a bit of deep diving into
Promise.all
typescript definition. The final trick is this:not beautiful, but works
This is just a little bit tricky. You want a generic, but because of the way function types are inferred the most obvious way to do it fails:
The compiler can’t or won’t infer the union of the return values of the thunks for
T
. You can work around this by declaring a function constraint instead and extracting the return value’s type:Note that this does not treat the array as a tuple but rather the way Typescript normally treats heterogeneous arrays, i.e. as a union of the possible types. The function signature is a bit more complex, but it provides enough hints to the compiler to get you what you want.
Playground