What is the Awaited Type in TypeScript?
The Awaited
type in TypeScript is a utility type that allows you to unwrap the value type that a Promise
resolves to. This is especially handy in TypeScript, which deeply cares about types and makes sure you're always aware of what type a certain value is.
How does it work?
Consider the basic definition of a Promise
. If you have a Promise
that resolves to a string, its type would be Promise<string>
. If you wanted to know the type that the Promise
resolves to (in this case, string
), you could use the Awaited
type.
Basic Usage
Let's dive into a simple example:
type MyPromise = Promise<string>; type ResolvedType = Awaited<MyPromise>; // This is equivalent to type ResolvedType = string
In this example, ResolvedType
would be of type string
, because that's the type that MyPromise
resolves to.
Nested Promises
One of the key features of the Awaited
type is its ability to handle nested Promise
values. Consider a situation where you have a Promise
that resolves to another Promise
which then resolves to a number:
type NestedPromise = Promise<Promise<number>>;
If you use the Awaited
type on NestedPromise
, you'll get the innermost resolved value type:
type ResolvedNestedType = Awaited<NestedPromise>; // This is equivalent to type ResolvedNestedType = number
Even though our NestedPromise
is two layers deep, the Awaited
type correctly identifies the type that we'll eventually get after all promises are resolved.
Why use Awaited
?
While TypeScript can often infer the resolved type of a Promise
in many contexts (like within an async function), there are scenarios where being explicit can offer more clarity or is necessary due to TypeScript's type system intricacies.
Additionally, Awaited
can be particularly useful in generic contexts where the exact type wrapped in a Promise
might be unknown.
Caveats
- Error Handling: It's worth noting that the
Awaited
type does not account for potential rejections of a promise. It assumes the promise will resolve successfully. Always handle potential rejections in your actual code. - Not a Runtime Feature: Like all TypeScript types,
Awaited
does not exist at runtime. It's purely a compile-time construct. - TypeScript Version: The
Awaited
type was introduced in TypeScript 4.1. Ensure you're using this version or a later one to leverage this utility type.
Practical Application: Async Functions
When dealing with async
functions, TypeScript often automatically infers the return type. But for better type clarity or when defining type contracts (like in interfaces or type aliases), Awaited
can be of great help.
Consider an API service function:
interface ApiService { fetchData: () => Promise<SomeDataType>; }
If you're writing a function that calls fetchData
and processes its result, you might use Awaited
to infer the exact type:
type FetchedData = Awaited<ReturnType<ApiService['fetchData']>>;
Here, FetchedData
would be of type SomeDataType
, giving you a direct reference to the fetched data's type without the wrapping promise.
In summary, the Awaited
type in TypeScript provides a powerful way to infer and work with the resolved values of promises, making type manipulations clearer and more intuitive in various scenarios.
Invite only
We're building the next generation of data visualization.
How to turn webpages into editable canvases with a JavaScript bookmarklet
Kris Lachance
How to fix the "not all code paths return a value" issue in TypeScript
Kris Lachance
Working with WebSockets in Node.js using TypeScript
Kris Lachance
Type Annotations Can Only Be Used in TypeScript Files
Kris Lachance
Guide to TypeScript Recursive Type
Kris Lachance
How to Configure Knex.js with TypeScript
Kris Lachance