oxc-project/oxc · warning · OxcDiagnostic
Using a spread operator here creates a new {noun} unnecessar
Error message
Using a spread operator here creates a new {noun} unnecessarily. What it means
Diagnostic from the oxlint rule `unicorn/no-useless-spread`. This variant (`clone`) fires when a single-element spread copies an expression that constant evaluation proves already returns a fresh array or object: `[...foo.map(x => x)]`, `[...Object.keys(foo)]`, `[...foo.slice(1)]`, `[...foo.split('|')]`, `[...Array.from(foo)]`, `[...await Promise.all(foo)]`, `[...new Array(3)]`, `{...(foo ? {a: 1} : {a: 2})}`. The message fills `{noun}` with 'array' or 'object' and the help names the producing method when a short snippet exists. Autofix removes the spread (for `new Array(n)` it appends `.fill()` to preserve holes).
Source
Thrown at crates/oxc_linter/src/rules/unicorn/no_useless_spread/mod.rs:64
.with_help("Consider removing the spread operator.")
.with_label(span)
}
fn iterable_to_array_in_for_of(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Using a spread operator here creates a new array unnecessarily.")
.with_help("`for…of` can iterate over iterable, it's unnecessary to convert to an array.")
.with_label(span)
}
fn iterable_to_array_in_yield_star(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Using a spread operator here creates a new array unnecessarily.")
.with_help("`yield*` can delegate to another iterable, so it's unnecessary to convert the iterable to an array.")
.with_label(span)
}
fn clone(span: Span, is_array: bool, method_name: Option<&str>) -> OxcDiagnostic {
let noun = if is_array { "array" } else { "object" };
OxcDiagnostic::warn(format!("Using a spread operator here creates a new {noun} unnecessarily."))
.with_help(
if let Some(method_name) = method_name {
format!("`{method_name}` returns a new {noun}. Spreading it into an {noun} expression to create a new {noun} is redundant.")
} else {
format!("This expression returns a new {noun}. Spreading it into an {noun} expression to create a new {noun} is redundant.")
}).with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct NoUselessSpread;
declare_oxc_lint!(
/// ### What it does
///
/// Disallows using spread syntax in following, unnecessary cases:
///
/// - Spread an array literal as elements of an array literalView on GitHub (pinned to a3d33dda7c)
Solutions
- Remove the spread: `[...foo.map(x => x * 2)]` -> `foo.map(x => x * 2)`.
- Apply the rule's autofix; note `[...new Array(3)]` becomes `new Array(3).fill()`.
- Keep the spread when cloning a plain identifier (`[...arr]`) - that case is allowed by design.
- If the expression's type is opaque and the clone is deliberate, disable the rule inline.
Example fix
// before
function foo(bar) {
return [...bar.map(x => x * 2)];
}
// after
function foo(bar) {
return bar.map(x => x * 2);
} Defensive patterns
Strategy: validation
Validate before calling
# detect spreading expressions that already return fresh arrays/objects rg -n --type js -U '\[\.\.\.(?:\w+\.(?:map|filter|concat|slice|splice|flat|flatMap|toSorted|toReversed|toSpliced|with|split)\(|Object\.(?:keys|values)\(|Array\.(?:from|of)\(|await Promise\.(?:all|allSettled)|new Array\()' src/
Prevention
- Learn which methods already return new containers (map, filter, slice, Object.keys, Promise.all, Array.from).
- Use `[...x]` only to shallow-clone a plain identifier that may be an array/set.
- Note the `new Array(n)` special case: the fix is `.fill()`, since spread of a holey array also drops holes.
When it happens
Trigger: `[...foo.concat(bar)]`, `[...foo.copyWithin(-2)]`, `[...foo.filter(bar)]`, `[...foo.flat()]`, `[...foo.map(bar)]`, `[...foo.toSorted()]`, `[...foo.with(0, bar)]`, `[...Object.values(foo)]`, `[...Array.of()]`, `[...new Array(3)]`, `{...(foo ? Object.entries(obj).reduce(fn, {}) : {a: 2})}`. Not fired for spreading a plain identifier (`[...arr]` is a legitimate shallow clone) or methods whose result type cannot be proven (e.g. `[...array.unknown()]`).
Common situations: 'Just to be safe' copying around expressions that already allocate (`.map()`, `Object.keys`, `Promise.all`), common in React prop objects and utility code. Hits projects with the oxlint correctness category enabled.
Related errors
- Empty fallbacks in spreads are unnecessary
- Using a spread operator here creates a new {arr_or_obj} unne
- Using a spread operator here creates a new array unnecessari
- `{ctor_name}` accepts an iterable, so it's unnecessary to co
- Prefer consistent types when spreading a ternary in an array
AI-assisted analysis of oxc-project/oxc@a3d33dda7c (2026-08-20).
Data as JSON: /api/errors/6d30ea1015f93587.
Report an issue: GitHub.