Summary
The type checker infers a free generator function's call result as iterable, but a generator method's call result is left as <inferred>, so spreading (or any iterable use of) it is rejected:
function* freeGen() { yield 1; yield 2; }
console.log([...freeGen()].length); // OK → 2
class C { *m() { yield 1; yield 2; } }
console.log([...new C().m()].length); // Type Error
// "Spread expression must be an iterable type (array, iterator, set, map, string, or generator),
// got '<inferred>'."
The same applies to for (const x of new C().m()) only working because the iterator protocol is checked structurally there, whereas spread/Array.from go through the stricter iterable-type check.
Cause (likely)
The return type of a *method() isn't being resolved to Generator<…>/IterableIterator<…> the way a top-level function* is — it surfaces as <inferred>. The iterable check in the spread path then fails. (Interpreter and compiled execution both handle the value correctly at runtime — this is purely a static-typing gap.)
Workaround
Iterate with for…of and accumulate, or annotate the method's return type explicitly (*m(): Generator<number> { … }).
Discovered
While smoke-testing generator changes (#435/#669). Independent of those fixes.
Summary
The type checker infers a free generator function's call result as iterable, but a generator method's call result is left as
<inferred>, so spreading (or any iterable use of) it is rejected:The same applies to
for (const x of new C().m())only working because the iterator protocol is checked structurally there, whereas spread/Array.fromgo through the stricter iterable-type check.Cause (likely)
The return type of a
*method()isn't being resolved toGenerator<…>/IterableIterator<…>the way a top-levelfunction*is — it surfaces as<inferred>. The iterable check in the spread path then fails. (Interpreter and compiled execution both handle the value correctly at runtime — this is purely a static-typing gap.)Workaround
Iterate with
for…ofand accumulate, or annotate the method's return type explicitly (*m(): Generator<number> { … }).Discovered
While smoke-testing generator changes (#435/#669). Independent of those fixes.