TypeScript Advanced: The Type System
Typing Async Code and Overloads
In this lesson you will
- Type promises and async functions
- Use Awaited and typed results with Promise.all
- Write function overloads
Introduction
Asynchronous code is where untyped mistakes love to hide: forgetting to wait for a result, or treating a promise as if it were its value. TypeScript can catch these. This lesson also covers overloads, a way for one function to have several precise signatures.
Promises are typed
A promise carries the type of the value it will eventually hold: Promise<number> will produce a number later.
Inside .then, TypeScript knows n is a number.
async functions
An async function always returns a promise, and TypeScript wraps the type for you. If you write : number, that is an error, because the real type is Promise<number>.
Forgetting await is one of the most common bugs in async code, and here the compiler spots it.
Quick quiz
What is the type of const x = getName() if getName is async and returns a string?
Typed error handling
In a catch block, the error is unknown under strict mode. Check it before using it.
Anything can be thrown in JavaScript, not only Error objects, so unknown is the honest type.
Awaited
Awaited<T> unwraps promises, even nested ones. It gives you the type of "what you get after await".
Combining ReturnType and Awaited is a standard way to get the result type of an async function without writing it twice.
Promise.all keeps the types
Promise.all takes a list of promises and returns one promise of their results. TypeScript keeps each position's type.
n is a number, t is a string and f is a boolean. The compiler tracks them by position.
Overloads
Sometimes the return type depends on the argument. Overloads declare several signatures, followed by one implementation that handles them all.
Callers see only the overload signatures (the first two), never the implementation signature. Each call gets exactly the right return type.
Overloads add complexity. Often a generic with a conditional type, or a union of simple functions, is clearer. Reach for overloads when the relationship between inputs and outputs cannot be expressed another way.
Quick quiz
In a set of overloads, which signature can callers see?
Try it yourself
The function sleepThenDouble below is async, but the line using it forgot to wait for the result. Fix the code so that it compiles and prints 20.
Summary
- A promise has a type:
Promise<T>. Anasyncfunction returnsPromise<T>, andawaitunwraps it. Awaited<ReturnType<typeof fn>>gives the resolved type of an async function.catchvariables areunknown.Promise.allkeeps the type of each result by position.- Overloads give one function several precise signatures, with a single implementation behind them.
Lesson complete
+20 XP
Nice work. Keep going while it is fresh.
Sources and further reading