← Back to TypeScript Course | Chapter 21: Symbols and Iterators | Lesson 3 of 6

Iterator Protocol

The iterator protocol defines objects that produce values one at a time through a next method. TypeScript can describe iterators with the built-in Iterator type and related iterable types.
Syntax
typescript
const iterable = {
  [Symbol.iterator](): Iterator<Type> {
    return { next: () => ({ value: item, done: false }) };
  },
};

Basic Iterator

An iterator is any object with a next method that returns an object containing value and done properties — that single method is the entire contract the iterator protocol requires.

Example: Basic Iterator

typescript
const iterator = {
  count: 0,
  next() {
    this.count++;
    return { value: this.count, done: this.count > 3 };
  },
};
console.log(iterator.next());

IteratorResult

An IteratorResult describes exactly what next returns: either a yielded value paired with done: false, or a completed result paired with done: true and typically no meaningful value.

Example: IteratorResult

typescript
function makeCounter(): { next(): IteratorResult<number> } {
  let count = 0;
  return {
    next: () => count < 3 ? { value: count++, done: false } : { value: undefined, done: true },
  };
}
const counter = makeCounter();
console.log(counter.next());

Iterable and Iterator

An iterable object provides a method under the well-known Symbol.iterator key that returns an iterator — this is the specific thing that lets a value be used with for...of, the spread operator, and destructuring.

Example: Iterable and Iterator

typescript
const range = {
  [Symbol.iterator]() {
    let n = 0;
    return { next: () => n < 3 ? { value: n++, done: false } : { value: undefined, done: true } };
  },
};
console.log([...range]);

Manual Iterator Consumption

You can consume an iterator manually by repeatedly calling next and checking the done flag yourself, which is exactly what for...of does under the hood on your behalf.

Example: Manual Iterator Consumption

typescript
const arr = [1, 2, 3];
const it = arr[Symbol.iterator]();
let result = it.next();
while (!result.done) {
  console.log(result.value);
  result = it.next();
}

Typed Iterable Classes

A class can implement the generic Iterable<T> interface to expose a properly typed Symbol.iterator method, letting its instances participate in every language feature built on the iteration protocol.

Example: Typed Iterable Classes

typescript
class NumberRange implements Iterable<number> {
  constructor(private end: number) {}
  [Symbol.iterator](): Iterator<number> {
    let n = 0;
    const end = this.end;
    return { next: () => n < end ? { value: n++, done: false } : { value: undefined, done: true } };
  }
}
console.log([...new NumberRange(3)]);
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Returning done: true too early or never, so a loop over the iterator never ends or skips the last value.
  2. Writing a next() method that does not return an object with value and done.
  3. Trying for...of on an object that only has next(), when it needs a [Symbol.iterator]() method.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.