AceDevHub
Production TypeScriptFree

Typing Async and Promises

Type async functions, Promise chains, and error handling — await narrowing, Promise.all typing, and Result patterns for failures.

AdvancedFreeAsync

async functions always return Promises — even when you return a plain value, TypeScript wraps it as Promise<T>. await unwraps Promise types inside async bodies. Typing async code correctly prevents forgetting to await, mishandling rejected promises, and losing error types in catch blocks.

Promise<T> is a generic — the type parameter is the resolved value. Promise<void> resolves with no useful value. Promise<never> or Promise that only rejects models operations that always fail. Combine with Result unions from earlier lessons for typed error paths without try/catch ambiguity.

Async function return types

Explicit Promise<User> on exports documents async contracts. Inference works: async function fetchUser(): auto-infers Promise<User> from return statements. Returning a non-Promise value inside async still produces Promise wrapper at runtime.

async-return.ts
Loading editor…

await and narrowing

await only works inside async functions or top-level modules configured for it. After await, the value has the unwrapped type — Promise<string> awaited becomes string. Union promises require narrowing after await if resolution type varies.

await-narrow.ts
Loading editor…
Outputconsole
TEXT or 42

Promise.all and concurrent typing

Promise.all on a tuple of promises returns a tuple of resolved types — order preserved. Promise.all on Promise<T>[] returns T[]. Promise.allSettled returns status-discriminated results — never rejects the aggregate promise.

promise-all.ts
Loading editor…

Typed errors and Result pattern

try/catch gives unknown in catch under useUnknownInCatchVariables — narrow before use. Result<T, E> avoids throw for expected failures — callers handle ok: false explicitly with typed error payloads.

result-async.ts
Loading editor…
PatternType
async fnPromise<T>
awaitunwraps Promise
Promise.all tupletuple of results
Resulttyped error path
  • async always returns Promise
  • await unwraps inside async
  • Promise.all preserves tuple types
  • Result for expected failures
  1. 1Annotate Promise return on exports
  2. 2await narrows after resolution
  3. 3Handle rejections explicitly
  4. 4Next: runtime validation with Zod