Iterator Protocol
In this page:
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
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
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
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
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
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)]);
Chapter Quiz — Complete all 6 topics to unlock
0/6 topics done
Complete these topics first: