Skip to main content
The for-await-of statement creates a loop that iterates over asynchronous iterable objects—objects that implement the [Symbol.asyncIterator]() method. It sequentially pauses the execution of the containing async function or block at the loop header until each yielded Promise resolves, extracting the fulfilled value into the loop variable before executing the block.

Technical Mechanics

Under the hood, the for-await-of loop interacts with the AsyncIterator protocol. When the loop initializes, it calls the [Symbol.asyncIterator]() method on the target object to retrieve an asynchronous iterator. During each iteration:
  1. The loop invokes the next() method on the iterator.
  2. next() returns a Promise<IteratorResult<T>>.
  3. The loop implicitly awaits this Promise at the loop header.
  4. Upon resolution, if the IteratorResult has done: false, the value property is assigned to the loop variable, and the block executes.
  5. If the IteratorResult has done: true, the loop terminates.

TypeScript Typing

TypeScript strictly types the for-await-of loop using the built-in AsyncIterable<T> and AsyncIterator<T> interfaces. The loop variable’s type is automatically inferred based on the generic type parameter T of the iterable.

Synchronous Iterable Fallback

If the target object does not implement [Symbol.asyncIterator]() but does implement the synchronous [Symbol.iterator]() (such as a standard Array), for-await-of will consume the synchronous iterable. If the synchronous iterable yields Promises (e.g., Iterable<Promise<T>>), the loop will await each Promise sequentially.

Compiler Configuration

To use for-await-of in TypeScript, specific tsconfig.json compiler options must be configured depending on your target environment:
  • lib: Must include "ES2018.AsyncIterable" (or a broader library like "ES2018") to provide the global type definitions for Symbol.asyncIterator, AsyncIterable, and AsyncIterator.
  • target: If set to "ES2018" or higher, TypeScript emits native for-await-of syntax. If targeting older environments (such as "ES5" or "ES6"), TypeScript automatically downlevels the loop using the __asyncValues helper function.
  • Downleveling: Unlike synchronous iteration (for...of), for-await-of does not require the "downlevelIteration": true flag to be downleveled. TypeScript always transpiles it when targeting pre-ES2018 environments. However, a runtime polyfill for Symbol.asyncIterator must be present in the execution environment for the emitted code to function correctly.
Tired of Poor TypeScript Skills? Fix That With Deep Grasping!Learn More