For runtime behavior—async function*, for await..of, and the async iterator protocol—see Async iterators and for await..of.
TypeScript adds static types on top of JavaScript async generators. Values yielded, values passed back into yield, and the final return type can each be described separately.
AsyncGenerator yield, return, and next
AsyncGenerator<TYield, TReturn, TNext> parameterizes:
TYield— type of values produced byyieldTReturn— type passed toreturn()(defaults tovoid)TNext— type of argument sent intonext()(defaults tounknown)
type Person = { name: string; title: string };
async function* getItems( items: Person[],): AsyncGenerator<Person, void, unknown> { for (const item of items) { await new Promise((r) => setTimeout(r, 100)); yield item; }}Typing for await..of consumers
Parameters typed as AsyncIterable<T> accept async generators, readable streams (where typings allow), and custom [Symbol.asyncIterator]() implementations:
async function renderOverTime(source: AsyncIterable<Person>) { for await (const item of source) { console.log(`${item.name} ${new Date().toLocaleTimeString()}`); }}
await renderOverTime(getItems([{ name: "Ada", title: "Engineer" }]));Use AsyncIterator<T, TReturn, TNext> when you hold the iterator object and call next() manually.
Inference and explicit annotations
TypeScript usually infers AsyncGenerator from async function* bodies. Annotate the return type when you implement an interface or export a public API surface:
interface LineSource { lines(): AsyncGenerator<string>;}
class FileLines implements LineSource { async *lines() { yield "first"; }}If yield types widen unexpectedly, add an explicit return type on the generator function or type the yield expression.
Strictness and Promise results
Each next() on an async iterator returns Promise<IteratorResult<TYield, TReturn>>. Under strict, handle done: true before using value:
async function first<T>(it: AsyncIterator<T>): Promise<T | undefined> { const { done, value } = await it.next(); return done ? undefined : value;}Rejected promises from the iterator propagate to the await on next() or to for await..of—same as ordinary async functions.