Issue
Say I have the following code:
async promiseOne() {
return 1
} // => Promise<number>
const promisedOne = promiseOne()
typeof promisedOne // => Promised<number>
How would I go about extracting the the type of the promise result (in this simplified case a number) as it's own type?
Solution
As of Typescript 2.8, this is now possible by taking advantage of conditional types, here's a basic example: Playground
function promiseOne() {
return Promise.resolve(1)
}
const promisedOne = promiseOne()
// note PromiseLike instead of Promise, this lets it work on any thenable
type ThenArg<T> = T extends PromiseLike<infer U> ? U : T
type PromiseOneThenArg = ThenArg<typeof promisedOne> // => number
// or
type PromiseOneThenArg2 = ThenArg<ReturnType<typeof promiseOne>> // => number
This isn't a perfect solution. Promises cannot contain other promises. Promise<Promise<string>> isn't real, and the type you get if you await it should be string, but ThenArg will give Promise<string>.
TypeScript 4.1 includes support for recursive type aliases, which makes it possible to write the following. Playground
type ThenArgRecursive<T> = T extends PromiseLike<infer U> ? ThenArgRecursive<U> : T
type Str = ThenArgRecursive<Promise<Promise<Promise<string>>>> // string
For older versions of TypeScript, which ban recursive types, you can work around this issue by using a recursive type alias, but be aware that this is officially not supported in those versions (though practically, usually fine). Playground
type ThenArgRecursive<T> = T extends PromiseLike<infer U>
? { 0: ThenArgRecursive<U>; 1: U }[U extends PromiseLike<any> ? 0 : 1]
: T
type Str = ThenArgRecursive<Promise<Promise<Promise<string>>>> // string
Answered By - Gerrit0
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.