Last updated: Feb 27, 2024
Reading timeยท4 min
To declare a function with a promise return type, set the return type of the function to a promise right after the function's parameter list.
If the return type of the function is not set, TypeScript will infer it.
// โ Named function function getPromise(): Promise<number> { return Promise.resolve(5); } // ๐๏ธ Unwrap promise type if necessary // ๐๏ธ type T = number type T = Awaited<ReturnType<typeof getPromise>>; // โ Named async function async function getPromise2(): Promise<number> { return 10; } // โ Arrow function const getPromise3 = (): Promise<string> => { return Promise.resolve('bobbyhadz.com'); };
Here are 3 more examples.
// โ Class method class A { async getPromise(): Promise<string> { return 'bobbyhadz.com'; } } // โ Using a type as Promise<Type> type Person = { name: string; age: number; }; async function getPromise4(): Promise<Person[]> { return [ { name: 'Bobby Hadz', age: 30, }, ]; }
You can set the return type of a function right after its parameter list.
function getPromise(a: number): Promise<number> { return Promise.resolve(a); }
If you need to unwrap the type of the Promise from a function's return type, use the Awaited utility type.
function getPromise(a: number): Promise<number> { return Promise.resolve(a); } // ๐๏ธ Unwrap promise type if necessary // ๐๏ธ type T = number type T = Awaited<ReturnType<typeof getPromise>>;
The Awaited
utility type recursively unwraps a promise and returns its type.
// ๐๏ธ type A = string type A = Awaited<Promise<string>>;
The examples above show how to set the return type of a function to a promise containing different values.
The advantage of setting the return type of the function explicitly is that the type checker would throw an error if you try to return a promise of a different type.
async function getPromise2(): Promise<number> { // โ๏ธ Type 'string' is not assignable to type 'number'.ts(2322) return 'bobbyhadz.com'; }
If you don't explicitly set the return type of the function, TypeScript will infer it.
// ๐๏ธ function getPromise2(): Promise<string> async function getPromise2() { return 'bobbyhadz.com'; }
If your function returns a Promise that may contain different values, use a union to specify the function's return type.
async function getPromise2(): Promise<string | null> { if (Math.random() > 0.5) { return null; } return 'bobbyhadz.com'; }
The function above returns a Promise that contains a string
or a null
value.
If your function returns a Promise that unwraps into an array of objects, it's more readable to use a type or an interface.
type Person = { name: string; age: number; }; async function getPromise4(): Promise<Person[]> { return [ { name: 'Bobby Hadz', age: 30, }, ]; }
The function above returns a Promise that contains an array of objects of type
Person
.
Use the Awaited
utility type to get the return type of a promise in
TypeScript.
The Awaited
utility type is used to recursively unwrap Promises and get their
return type.
// ๐๏ธ type A = string type A = Awaited<Promise<string>>; // ๐๏ธ type B = string type B = Awaited<Promise<Promise<string>>>; // ๐๏ธ C = boolean | number type C = Awaited<boolean | Promise<number>>; async function sum(a: number, b: number): Promise<number> { return a + b; } // ๐๏ธ type D = number type D = Awaited<ReturnType<typeof sum>>;
We used the Awaited utility type to get the return type of a couple of Promises in the examples.
The type is used to recursively unwrap a Promise and get its return type.
The second example shows that we can unwrap the type of the Promise even if it's nested.
// ๐๏ธ type B = string type B = Awaited<Promise<Promise<string>>>;
If you need to unwrap the return type of a promise from a function's return type, use the ReturnType utility type.
function multiply(a: number, b: number): Promise<number> { return Promise.resolve(a * b); } // ๐๏ธ type E = number type E = Awaited<ReturnType<typeof multiply>>;
The ReturnType
utility type constructs a type consisting of the function's
return type.
async
functionYou can use the same approach to unwrap the return type of an async
function.
Note that async
functions always return a Promise.
async function sum(a: number, b: number): Promise<number> { return a + b; } // ๐๏ธ type D = number type D = Awaited<ReturnType<typeof sum>>;
This approach also works with built-in methods like Promise.all
and
Promise.race
.
async function getArr(a: number, b: number): Promise<[number, string]> { const result = await Promise.all([ Promise.resolve(5), Promise.resolve('bobbyhadz.com'), ]); return result; } // ๐๏ธ [number, string] type E = Awaited<ReturnType<typeof getArr>>;
If you need to pass a function as a parameter, check out the following article.
You can learn more about the related topics by checking out the following tutorials: