How to use generator function in typescript
The next
method exists on the generator that the function returns, not on the generator function itself.
export default class GeneratorClass {
constructor() {
const iterator = this.generator(10);
iterator.next();
}
*generator(count:number): IterableIterator<number> {
while(true)
yield count++;
}
}
To solve the problem, it is very important to know the differences between generator functions (generators for short) and their return values.
A generator function (marked by the asterisk) is a function, which returns a generator object. The generator object fulfills the requirements of an iterator and an iterable.
Iterators have a next
method (that's the method you are looking for in your question). And iterables have a property called Symbol.iterator
(specifying a default iterator), which makes them usable in for-loops.
Because a generator function returns a generator object and a generator object is an iterable iterator, you have to declare a return type of IterableIterator
. In your case it will be IterableIterator<number>
.
Because the terms here are confusingly similar, I have recorded a Generator tutorial which explains the differences. Make sure to set your target
to es6
in your tsconfig.json
, when using generator functions.
Here is another example which uses the Generator type of typescript. Some of the types at the assignment of iterators e.g. const iterator: Generator<number>
can be omitted since TS can infer them. However I included them in this example to be more explicit.
class GeneratorClass {
*generator(count:number): Generator<number> {
while(count < 3)
yield count++;
}
}
const generatorObject = new GeneratorClass();
// Getting our generator object which we can use as an iterator.
const iterator: Generator<number> = generatorObject.generator(1);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
/*
[LOG]: {
"value": 1,
"done": false
}
[LOG]: {
"value": 2,
"done": false
}
[LOG]: {
"value": undefined,
"done": true
}
*/
// Alternative more clean for of syntax.
// For of can iterate over any iterable
// Can be used since every Generator is an Iterator
const iterator2: Generator<number> = generatorObject.generator(1);
I was seeing this error because my tsconfig.json was targeting es5
.
I simply changed (excerpted) from:
"target": "es5",
"lib": [
"es5",
"es2015.promise"
]
to:
"target": "es6",
"lib": [
"es6"
]
and the error went away.
Note: For VS Code I needed to reload the window for IntelliSense to recognize the change.