oxc-project/oxc · warning · OxcDiagnostic

`{description}` accepts an iterable, `.toArray()` is unneces

Error message

`{description}` accepts an iterable, `.toArray()` is unnecessary.

What it means

Diagnostic from the oxlint rule `unicorn/no-useless-iterator-to-array` (nursery). This variant fires when `Iterator.prototype.toArray()` (ES2025 iterator helpers) feeds a consumer that already accepts any iterable: the `Set`/`Map`/`WeakSet`/`WeakMap` constructors, typed-array constructors, `Array.from`, `TypedArray.from`, `Object.fromEntries`, and `Promise.all`/`allSettled`/`any`/`race`. The `{description}` placeholder is filled with the consumer, e.g. `new Set(…)` or `Array.from(…)`. Constructor and `.from` cases get an autofix; the Promise cases are reported as suggestions because removing `.toArray()` can turn a synchronous throw into an async rejection.

Source

Thrown at crates/oxc_linter/src/rules/unicorn/no_useless_iterator_to_array.rs:21

    ast::{
        CallExpression, Expression, ForOfStatement, FormalParameters, NewExpression, SpreadElement,
        YieldExpression,
    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::{GetSpan, Span};

use crate::{
    AstNode,
    ast_util::{is_method_call, is_new_expression},
    context::LintContext,
    fixer::{RuleFix, RuleFixer},
    rule::Rule,
};

fn iterable_accepting_diagnostic(span: Span, description: &str) -> OxcDiagnostic {
    OxcDiagnostic::warn(format!(
        "`{description}` accepts an iterable, `.toArray()` is unnecessary."
    ))
    .with_label(span)
}

fn for_of_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`for…of` can iterate over an iterable, `.toArray()` is unnecessary.")
        .with_label(span)
}

fn yield_star_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("`yield*` can delegate to an iterable, `.toArray()` is unnecessary.")
        .with_label(span)
}

fn spread_diagnostic(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Spread works on iterables, `.toArray()` is unnecessary.").with_label(span)
}

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Remove the `.toArray()` call and pass the iterator straight through: `new Set(iterator.toArray())` -> `new Set(iterator)`.
  2. For Promise combinators, apply the suggestion and be aware iteration errors now reject the promise instead of throwing synchronously.
  3. Keep `.toArray()` when you afterwards need array-only APIs (`.sort()`, `.at()`, indexing) - the rule deliberately does not flag those.
  4. On runtimes without iterator-helper support, keep the conversion and disable the rule.

Example fix

// before
const set = new Set(iterator.toArray());

// after
const set = new Set(iterator);
Defensive patterns

Strategy: validation

Validate before calling

# detect toArray() feeding iterable-accepting consumers
rg -n --type js '(?:new (?:Weak)?(?:Set|Map)|(?:Int8|Uint8|Uint8Clamped|Int16|Uint16|Int32|Uint32|Float16|Float32|Float64|BigInt64|BigUint64)Array|Array\.from|Object\.fromEntries|Promise\.(?:all|allSettled|any|race))\([^)]*toArray\(\)' src/

Prevention

When it happens

Trigger: `new Set(iterator.toArray())`, `new Map(iterator.toArray())`, `new Int8Array(iterator.toArray())`, `Array.from(iterator.toArray())`, `Uint8Array.from(iterator.toArray())`, `Object.fromEntries(iterator.toArray())`, `Promise.all(iterator.toArray())`. Skipped for optional forms (`iterator?.toArray()`, `.toArray?.()`), computed access `iterator['toArray']()`, calls with arguments `iterator.toArray(true)`, and namespaced callees like `new foo.Set(...)`.

Common situations: Codebases on Node 22+ or TS 5.6+ that adopted iterator helpers (`.take()`, `.map()`, `.drop()`) and convert to arrays out of habit before handing off to builtins. Appears when enabling unicorn nursery rules or after upgrading oxlint to a version that ships this rule.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/4167692b1a684a69. Report an issue: GitHub.