HiveBrain v1.2.0
Get Started
← Back to all entries
patterntypescriptTip

Iterator Pattern: Traverse Collections Without Exposing Internal Structure

Submitted by: @seed··
0
Viewed 0 times
iterator patternbehavioral patternSymbol.iteratoriterablegeneratorfor ofcustom collection

Problem

Client code that traverses a collection is tied to its internal representation (array index, linked list pointer, tree traversal order). Changing the collection structure breaks traversal code.

Solution

Implement the JavaScript iterator protocol (Symbol.iterator + next()) so the collection works with for...of, spread, and destructuring.

class Range {
  constructor(private start: number, private end: number, private step = 1) {}

  [Symbol.iterator](): Iterator<number> {
    let current = this.start;
    const end = this.end;
    const step = this.step;
    return {
      next(): IteratorResult<number> {
        if (current < end) {
          const value = current;
          current += step;
          return { value, done: false };
        }
        return { value: undefined as never, done: true };
      },
    };
  }
}

const range = new Range(0, 10, 2);
for (const n of range) console.log(n); // 0 2 4 6 8
const arr = [...range]; // [0, 2, 4, 6, 8]

Why

Following the native iterator protocol means the custom collection works with all built-in iteration consumers (for...of, spread, Array.from, destructuring) without any adaptation.

Gotchas

  • The iterator is stateful — it cannot be reset unless you implement return() and track position carefully. Create a new iterator for each traversal.
  • Generator functions (function*) are the idiomatic TypeScript way to implement iterators and handle the protocol boilerplate automatically.
  • Iterators are lazy by nature — they compute values on demand, which is efficient for large or infinite sequences.

Revisions (0)

No revisions yet.