π Disallow unnecessary .toArray() on iterators.
πΌ This rule is enabled in the following configs: β
recommended, βοΈ unopinionated.
π§π‘ This rule is automatically fixable by the --fix CLI option and manually fixable by editor suggestions.
Iterator.prototype.toArray() converts an iterator to an array. However, this conversion is unnecessary in the following cases:
-
The following builtins accept an iterable, so converting to an array first is unnecessary:
MapconstructorWeakMapconstructorSetconstructorWeakSetconstructorTypedArrayconstructorArray.from(β¦)TypedArray.from(β¦)Object.fromEntries(β¦)
-
forβ¦ofcan iterate over any iterable, so converting to an array first is unnecessary. -
yield*can delegate to any iterable, so converting to an array first is unnecessary. -
Promise.{all,allSettled,any,race}(β¦)accept an iterable, so.toArray()is unnecessary. However, removing it can change a synchronous throw into an asynchronous rejection when iteration fails, so these cases are reported as suggestions rather than autofixes. -
The spread operator (
...) works on any iterable, so converting to an array before spreading is unnecessary:[...iterator.toArray()]β[...iterator]call(...iterator.toArray())βcall(...iterator)
-
Some
Arraymethods also exist onIterator, so converting to an array to call them is unnecessary:.every().find().forEach().reduce().some()
However, Array callbacks receive additional arguments (e.g., the 3rd array argument) that Iterator callbacks do not, so removing .toArray() can change behavior if the callback uses those arguments. These cases are reported as suggestions rather than autofixes.
This rule does not flag .filter(), .map(), or .flatMap() because their Iterator versions return iterators, not arrays, so the semantics differ.
// β
const set = new Set(iterator.toArray());
// β
const set = new Set(iterator);// β
const results = await Promise.all(iterator.toArray());
// β
const results = await Promise.all(iterator);// β
for (const item of iterator.toArray());
// β
for (const item of iterator);// β
function * foo() {
yield * iterator.toArray();
}
// β
function * foo() {
yield * iterator;
}// β
const items = [...iterator.toArray()];
// β
const items = [...iterator];// β
call(...iterator.toArray());
// β
call(...iterator);// β
iterator.toArray().every(fn);
// β
iterator.every(fn);// β
β `.filter()` returns an array on Array but an iterator on Iterator
iterator.toArray().filter(fn);