"A Promise per value. A stream the type system understands."
What async iterables are
An async iterable is an object with a [Symbol.asyncIterator]() method that returns an object with an async next(): Promise<{ value: T; done: boolean }> method. for await (const x of stream) walks through it, awaiting each value before continuing.
This is how Node.js streams, file line iterators, and HTTP-server request bodies are typed. Anywhere you have a series of values that arrive over time, async iterables are the canonical shape.
Generators that yield Promises
The easiest way to create an async iterable is an async generator: async function* gen(): AsyncIterable<number> { yield 1; yield 2; yield await fetchValue() }. Each yield produces one value of the stream; awaiting inside the generator pauses until the value is ready.
Difference from Promise<T[]>
A Promise<T[]> is one Promise that resolves to the full array. An AsyncIterable<T> is a stream — values arrive one at a time, and you can start processing the first before the last has arrived. For large data or slow producers, async iterables let you stream; for small batched data, a Promise<T[]> is simpler.
AsyncIterable<T> and for await. When all the values arrive together, reach for Promise<T[]>.