← Back to TypeScript Course | Chapter 15: TypeScript with APIs | Lesson 5 of 6

Async/Await with Types

Async and await make asynchronous TypeScript code easier to read by allowing Promise-based operations to look sequential. The return type of an async function is always a Promise of its declared result type.

Typed Async Functions

An async function's return type is automatically wrapped in Promise<T> by the compiler, so declaring a function as async (): Promise<number> and one declared async (): number behave identically once compiled.

Example: Typed Async Functions

typescript
async function getCount(): Promise<number> {
  return 5;
}
getCount().then((n) => console.log(n));

Awaiting Fetch Responses

Awaiting a typed fetch response — const data: User = await response.json() — resolves the promise's value with the annotated type, though remember .json() itself doesn't validate the shape, only assigns the type you assert.

Example: Awaiting Fetch Responses

typescript
interface User { name: string; }
async function getUser(): Promise<User> {
  const response = await fetch("data.php");
  const data: User = await response.json();
  return data;
}
getUser().then((u) => console.log(u.name));

Sequential Async Operations

Sequential async operations, each awaited one after another, type each intermediate result individually as it's produced, making each step's output available with full type information for the next step to consume.

Example: Sequential Async Operations

typescript
async function step1(): Promise<number> { return 1; }
async function step2(n: number): Promise<number> { return n + 1; }
async function run() {
  const a = await step1();
  const b = await step2(a);
  console.log(b);
}
run();

Parallel Async Operations

Parallel async operations run through Promise.all, which types its result as a tuple matching each input promise's resolved type in order, letting you destructure multiple concurrent results with full type safety.

Example: Parallel Async Operations

typescript
async function getA(): Promise<number> { return 1; }
async function getB(): Promise<string> { return "b"; }
async function run() {
  const [a, b] = await Promise.all([getA(), getB()]);
  console.log(a, b);
}
run();

Async Error Handling

Async error handling with try/catch types the caught value as unknown just like synchronous code, so narrowing it with instanceof Error before reading .message applies the same way inside an async function.

Example: Async Error Handling

typescript
async function risky(): Promise<number> {
  throw new Error("failed");
}
async function run() {
  try {
    await risky();
  } catch (err: unknown) {
    if (err instanceof Error) console.log(err.message);
  }
}
run();
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.