Skip to main content

Typing async functions

Basic syntax

A regular function:

javascript
function getUser(): Promise<{ id: number; name: string }> { return fetch("/api/user") .then(r => r.json()); // type T = { id: number; name: string } }

An async function (sugar):

javascript
async function getUser(): Promise<{ id: number; name: string }> { const r = await fetch("/api/user"); return r.json(); }

With async, TypeScript infers Promise<ReturnType> from the return on its own. Exported functions are better off annotated explicitly.


Common variants

javascript
async function ping(): Promise<void> { await fetch("/ping"); // returns nothing } function loadIds(): Promise<number[]> { return fetch("/ids").then(r => r.json()); } async function isOk(): Promise<boolean> { const r = await fetch("/health"); return r.ok; }

Generic functions

javascript
async function getJSON<T>(url: string, init?: RequestInit): Promise<T> { const r = await fetch(url, init); if (!r.ok) throw new Error(`HTTP ${r.status}`); return r.json() as Promise<T>; } // Usage const user = await getJSON<{ id: number; name: string }>("/api/user");

Errors and catch

Promises have no annotated rejection type (TypeScript does not know the "error type"). In catch, use unknown and narrowing:

javascript
try { await getUser(); } catch (e: unknown) { if (e instanceof Error) console.error(e.message); }

Useful utilities

  • Awaited<T> unwraps a promise:

    javascript
    type User = Awaited<ReturnType<typeof getUser>>; // { id: number; name: string }
  • PromiseSettledResult<T> for Promise.allSettled.

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.