Awaited<T>
Recursively unwraps the resolved type of a Promise or nested Promises, giving you the eventual value type.
Definition
type Awaited<T> = T extends null | undefined
? T
: T extends object & { then(onfulfilled: infer F, ...args: infer _): any }
? F extends (value: infer V, ...args: infer _) => any
? Awaited<V>
: never
: T;Examples
type A = Awaited<Promise<string>>;
// string
type B = Awaited<Promise<Promise<number>>>;
// number (recursively unwrapped)
type C = Awaited<boolean | Promise<string>>;
// boolean | stringasync function fetchUser(id: string) {
const res = await fetch(`/api/users/${id}`);
return res.json() as Promise<{ name: string; email: string }>;
}
type User = Awaited<ReturnType<typeof fetchUser>>;
// { name: string; email: string }
async function processUser() {
const user: User = await fetchUser("123");
console.log(user.name);
}async function loadData() {
const [users, posts, comments] = await Promise.all([
fetch("/api/users").then(r => r.json()) as Promise<string[]>,
fetch("/api/posts").then(r => r.json()) as Promise<number[]>,
fetch("/api/comments").then(r => r.json()) as Promise<boolean[]>,
]);
type Users = Awaited<Promise<string[]>>; // string[]
return { users, posts, comments };
}Common Use Cases
- 1Extracting the resolved value type from async functions
- 2Typing variables that store awaited promise results
- 3Working with Promise.all and Promise.race result types
- 4Unwrapping deeply nested promise chains
- 5Building type-safe async utility functions
Understanding Awaited<T>
Awaited<T> recursively unwraps the type inside a Promise, giving you the eventual resolved value type. For Promise<string>, it returns string. For Promise<Promise<number>>, it recursively unwraps to number. For non-promise types, it returns the type as-is.
This utility type was added in TypeScript 4.5 and models what the await keyword does at the type level. Before Awaited existed, developers had to write their own recursive unwrapping types, which were error-prone and didn't handle edge cases like thenable objects.
The most common use of Awaited is with ReturnType for async functions. Since async functions return a Promise, ReturnType<typeof asyncFn> gives you Promise<T>. To get just T, you wrap it: Awaited<ReturnType<typeof asyncFn>>. This pattern is ubiquitous in Next.js applications for typing the resolved data from server-side fetches.
Awaited also handles union types correctly. If T is boolean | Promise<string>, the result is boolean | string—each union member is processed independently, with promises being unwrapped and non-promises passing through.
The implementation handles thenable objects (objects with a then method), not just native Promises. This means it works correctly with promise-like objects from older libraries or custom implementations.
Awaited is the key to making Promise.all, Promise.race, Promise.allSettled, and Promise.any type-safe. The TypeScript standard library uses Awaited internally to type these methods, ensuring that the resolved array or value has the correct unwrapped types.
Related Types
ReturnType<T>Extracts the return type of a function type T, enabling you to reuse a function's output type without manual duplication.
Parameters<T>Extracts the parameter types of a function type T as a tuple, enabling you to reuse a function's argument types elsewhere.
Conditional TypesConditional types select one of two types based on a condition expressed as an extends clause, enabling type-level branching logic.
infer keywordThe infer keyword declares a type variable within a conditional type's extends clause, extracting and capturing part of a type for use in the true branch.
More Object & Function Types
Explore TypeScript Types
Browse our complete reference of 30 TypeScript utility types with definitions, examples, and explanations.