Reputation: 1825
I want to create a variable with some default values, that is an extended interface of the resolved return type from a promise. My function would be something like:
function getAge(): Promise<number> {
return new Promise((resolve) => {
resolve(42)
})
}
My variable with default values would be:
let user: { name: string, age: number } = { name: "", age: 0 }
I've tried using the ReturnType<>, however I can only seem to get the return type Promise<number>
, when I just want number returned.
Upvotes: 14
Views: 7591
Reputation: 335
You can use new Awaited type
for example:
let bar: Awaited<ReturnType<typeof foo>>
This works the same as the UnboxPromise
example from Titian Cernicova-Dragomir, but Awaited can deploy Promise recursively.
I liked Titian Chernikov-Dragomir's response (example `UnboxPromise').
Alternatively, you can define a type similar to ReturnType, only with the return value as a promise.
type ReturnPromiseType<T extends (...args: any) => Promise<any>> = T extends (...args: any) => Promise<infer R> ? R : any;
Example:
// Our declared type
type ReturnPromiseType<T extends (...args: any) => Promise<any>> = T extends (...args: any) => Promise<infer R> ? R : any;
// Let's imagine that we do not have direct access to this type (a typical case when using external libraries)
interface Foo {
a: string
}
// Here we already have access to the function, but we still don't have access to the return type.
function foo(): Promise<Foo> {
return Promise.resolve({
a: "abc"
})
}
(async () => {
let bar: ReturnPromiseType<typeof foo> // returns our interface/type Foo
let baz: any // any by default
bar = await foo();
baz = await foo();
// typeof bar
// in IDE shows - let bar: Foo
// typeof bar.a
// in IDE shows - (property) Foo.a: string
//typeof baz
// in IDE shows - any
//typeof baz.a
// in IDE shows - any
})();
Upvotes: 21
Reputation: 250106
You can use a conditional type to extract the value type of a promise:
function getAge(): Promise<{ name: string, age: number }> {
return new Promise((resolve) => {
resolve({ name: "", age: 42 })
})
}
type UnboxPromise<T extends Promise<any>> = T extends Promise<infer U> ? U: never;
let user: UnboxPromise<ReturnType<typeof getAge>> = { name: "", age: 0 }
Read more about conditional types here
Upvotes: 9