Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The for...of statement executes a loop that operates on a sequence of values sourced from an iterable object. It invokes the iterable protocol by calling the object’s [Symbol.iterator]() method, retrieving the values yielded by the iterator and abstracting away the manual management of loop counters or .next() state evaluations.

Syntax

for (const variable of iterable) {
  // execution block
}
  • variable: Receives the value yielded by the iterator on each step. It is typically declared with const or let. TypeScript automatically infers the type of this variable based on the generic type of the iterable.
  • iterable: Any object that structurally satisfies the iterable protocol, meaning it possesses a property with a Symbol.iterator key that returns an iterator.

Type Inference

TypeScript leverages the type signature of the iterable to enforce type safety within the loop block. If an array is typed as number[], the loop variable is strictly inferred as number.
const sequence: number[] = [10, 20, 30];

// TypeScript infers 'item' as 'number'
for (const item of sequence) {
    console.log(item.toExponential());
}

Implementing the Iterable Protocol

To utilize a for...of loop on a custom TypeScript class or object, the entity must structurally satisfy the iterable protocol. Because TypeScript uses structural typing, an explicit implements Iterable<T> declaration is entirely optional. The object only needs to define a valid [Symbol.iterator]() method that returns an object conforming to the Iterator<T> interface, which in turn yields IteratorResult<T> objects.
class DataStream {
    private buffer: string[] = ["chunk1", "chunk2", "chunk3"];

    // Structurally satisfies Iterable<string>
    [Symbol.iterator](): Iterator<string> {
        let cursor = 0;
        const data = this.buffer;

        return {
            next(): IteratorResult<string> {
                if (cursor < data.length) {
                    return { done: false, value: data[cursor++] };
                }
                return { done: true, value: undefined };
            }
        };
    }
}

const stream = new DataStream();

// 'chunk' is inferred as 'string' based on the iterator's return type
for (const chunk of stream) {
    console.log(chunk);
}

Asynchronous Iteration

TypeScript supports the for await...of variant to consume objects implementing the AsyncIterable<T> protocol. This is used when the iterator’s next() method returns a Promise<IteratorResult<T>>.
async function consumeStream(stream: AsyncIterable<Uint8Array>): Promise<void> {
    for await (const chunk of stream) {
        // 'chunk' is inferred as 'Uint8Array'
        console.log(chunk.byteLength);
    }
}

Compiler Configuration (downlevelIteration)

When the TypeScript compiler target (compilerOptions.target) is set to ES5 or ES3, native support for the iterable protocol does not exist. By default, TypeScript will only allow for...of loops on standard Arrays and string types in these environments. To iterate over other iterables (like Map, Set, or custom iterable implementations) when targeting ES5/ES3, the downlevelIteration flag must be enabled in tsconfig.json.
{
  "compilerOptions": {
    "target": "ES5",
    "downlevelIteration": true
  }
}
When enabled, the compiler injects helper functions (such as __values) into the emitted JavaScript to manually emulate the ES6 iteration protocol, ensuring runtime compatibility at the cost of slightly increased bundle size.
Master TypeScript with Deep Grasping Methodology!Learn More