I have a generator method that adds asyncronously some stuff to an array and at the end yields each member with yield* array
like so:
while (!done) {
await promise;
yield* results; //<-- the array
results = []; //its emptied so as to not to yield dupes
done = !this.#eventsListened.has(eventName);
}
However our friendly neighbor tsc reports an error and I can't even begin to understand it or how to fix it. Can anybody explain what does this error mean and how am I supposed then to yield the contents of an array?
TS2766: Cannot delegate iteration to value because the 'next' method of its iterator expects type 'undefined', but the containing generator will always send 'unknown'.
Edit: the whole generator function follows
/**
* Returns an iterator that loops over caught events
* @yields Promise<Event|CustomEvent>
*/
async *on(eventName: string, options?: AddEventListenerOptions): AsyncGenerator<Event> {
if (this.#eventsListened.has(eventName)) {
return;
}
let results: Event[] = [];
let resolve: (value?: PromiseLike<Event> | Event) => void;
let promise = new Promise<Event>(r => (resolve = r));
let done = false;
this.#eventsListened.add(eventName);
if (typeof options === 'object' && typeof options.once !== 'undefined') {
throw new Error('options.once is not supported. Use EventTarget2.once instead');
}
const callback = (evt: Event) => {
results.push(evt);
resolve();
promise = new Promise<Event>(r => (resolve = r));
};
this.addEventListener('eventName', callback, options);
while (!done) {
await promise;
yield* results;
results = [];
done = !this.#eventsListened.has(eventName);
}
this.removeEventListener(eventName, callback);
}
Your main Problem is AsyncGenerator<Event>
... As you did not specify the third generic parameter, it's default value (unknown
) is used, and unknown
missmatches undefined
.
The missmatch occurs because the inner iterator does not expect any values passed into the iterator via next(value)
, therefore it's TNext
generic parameter is undefined
. As you yield*
that iterator, calling next(...)
on your generators iterator will call the inner iterator with the same arguments, therefore the arguments have to match.
Typescript infers the type of a generator function to AsyncGenerator<..., ..., undefined>
for exactly that reason, and you should do that too (as long as you dont want to pass values into the iterator with .next
): AsyncGenerator<Event, void, undefined>
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With