Recommended way to implement Iterator<T> in Typescript, before ES6
This is a duplicate of: typescript: make class objects iterable, but here's an answer to ES5
:
You want to use a ES6
feature:
One addition of ECMAScript 2015 (ES6) is not new syntax or a new built-in, but a protocol. This protocol can be implemented by any object respecting some conventions.
There are two protocols: The iterable protocol and the iterator protocol.
In a ES5
environment (compilation and/or runtime), and that's not something that you can do.
With that being said, you can get close enough because:
An object is an iterator when it knows how to access items from a collection one at a time, while keeping track of its current position within that sequence. In JavaScript an iterator is an object that provides a next() method which returns the next item in the sequence. This method returns an object with two properties: done and value.
So you can just return an object with a next
method and it's an iterator:
class Counter /* implements Iterator<number> */ {
private counter = 0;
//public next(): IteratorResult<number> {
public next(): { done: boolean, value: number } {
return {
done: false,
value: this.counter++
}
}
}
let c = new Counter();
console.log(c.next().value); // 0
console.log(c.next().value); // 1
console.log(c.next().value); // 2
The commented out parts will work with target ES6
but not when it's below that.
But if your runtime environment does support this feature then the compiled js will do the job just fine.
Related videos on Youtube
Alon
Updated on July 05, 2022Comments
-
Alon about 2 years
I have a project that includes many classes that ideally would implement the
Iterable<T>
and/orIterator<T>
interfaces. However I cannot seem to find a standard TypeScript definition of these interfaces (for example in typescript-collections or some similar package).I understand these are somewhat standardized in ECMAScript 6 through the
Symbol.iterator
mechanism, but my target is ECMAScript 5 and will stay so for the foreseeable future.Can I somehow get these interfaces without defining them myself (for future compatibility with other modules, for example)?
-
Alon almost 8 yearsThanks for your answer. What I was looking for was some sort of typescript pre-ES6 standard, but it seems that doesn't exist. For example if I'd like to implement a
sort(collection: Iterable<E>)
I would have to define theIterable
interface myself, if I understood correctly. -
Nitzan Tomer almost 8 yearsYes, that's correct, but if you're using the name
Iterable
then you need to think about what happens when you do move toES6
and that interface already exists.