unicorn/no-useless-iterator-to-array Nursery
What it does
Disallow unnecessary .toArray() on iterators.
Why is this bad?
Iterator.prototype.toArray() converts an iterator to an array. However, this conversion is unnecessary in many cases:
- The following builtins accept an iterable directly:
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. Removing.toArray()here can change a synchronous throw into an asynchronous rejection when iteration fails, so these cases are suggestions rather than autofixes.- The spread operator (
...) works on any iterable, so converting to an array first is unnecessary. - Some
Arraymethods also exist onIterator, so converting to an array to call them is unnecessary:.every().find().forEach().reduce().some()
Array callbacks receive additional arguments (for example, the 3rd array argument) that Iterator callbacks do not. Removing .toArray() can change behavior if callbacks depend on those extra arguments, so those cases are reported as suggestions.
This rule does not flag .filter(), .map(), or .flatMap() because their Iterator versions return iterators, not arrays, so the semantics differ.
Examples
Examples of incorrect code for this rule:
js
const set = new Set(iterator.toArray());
const results = await Promise.all(iterator.toArray());
for (const item of iterator.toArray());
function* foo() {
yield* iterator.toArray();
}
const items = [...iterator.toArray()];
call(...iterator.toArray());
iterator.toArray().every(fn);Examples of correct code for this rule:
js
const set = new Set(iterator);
const results = await Promise.all(iterator);
for (const item of iterator);
function * foo() {
yield * iterator;
}
const items = [...iterator];
call(...iterator);
iterator.every(fn);
`.filter()` returns an array on Array but an iterator on Iterator
iterator.toArray().filter(fn);How to use
To enable this rule using the config file or in the CLI, you can use:
json
{
"rules": {
"unicorn/no-useless-iterator-to-array": "error"
}
}ts
import { defineConfig } from "oxlint";
export default defineConfig({
rules: {
"unicorn/no-useless-iterator-to-array": "error",
},
});bash
oxlint --deny unicorn/no-useless-iterator-to-arrayVersion
This rule was added in v1.59.0.
