noUselessSpread (JavaScript)
Summary
Section titled “Summary”- Diagnostic Category:
lint/nursery/noUselessSpread - This rule has an unsafe fix.
- The default severity of this rule is information.
- Sources:
- Same as
unicorn/no-useless-spread
- Same as
How to configure
Section titled “How to configure”{ "linter": { "rules": { "nursery": { "noUselessSpread": "error" } } }}Description
Section titled “Description”Disallow spread syntax that has no effect.
Spread syntax (...) copies the items of an array, an object, or any other iterable value,
such as a Set or a generator.
In some places the copy is not needed:
- Spreading an array literal into another array literal, or into the arguments of a call. Write the elements directly instead.
- Spreading an object literal into another object literal. Write the properties directly instead.
- Creating an object that only contains spread properties to pass it to
Object.assign().Object.assign()already copies the properties of each argument, so pass the values directly. - Spreading an iterable into the only argument of
new Map(),new WeakMap(),new Set(), ornew WeakSet(). These constructors read a single iterable, so each item becomes a separate argument and only the first one is used. - Converting an iterable to an array before passing it to something that accepts any iterable:
a
for...ofloop,yield*,new Map(),new WeakMap(),new Set(),new WeakSet(),Array.from(),Object.fromEntries(),Promise.all(),Promise.allSettled(),Promise.any(),Promise.race(), and thefrom()method of typed arrays such asUint8Array.from(). - Copying an array that was just created by a method such as
concat(),slice(),toSorted(), orObject.keys().
The rule assumes that a method with one of these names returns a new array.
It can’t know whether a value such as foo in foo.slice() is an array or a string,
so it doesn’t offer a fix for concat() and slice(), which strings also have.
The rule doesn’t offer a fix for an object literal with a getter or a setter, such as { ...{ get value() {} } }.
Spreading the object reads the getter once and copies the value,
while writing the getter in the outer object would run it every time the property is read.
Spreading an array also turns empty slots into undefined.
If your code relies on that, disable the rule where needed.
Examples
Section titled “Examples”Invalid
Section titled “Invalid”const array = [first, ...[second, third]];code-block.js:1:23 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Spreading an array literal into another array literal is unnecessary.
> 1 │ const array = [first, ...[second, third]];
│ ^^^^^^^^^^^^^^^^^^
2 │
ℹ Write the elements directly in the surrounding array.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the spread and the square brackets.
1 │ const·array·=·[first,·...[second,·third]];
│ ---- -
const object = { first, ...{ second } };code-block.js:1:25 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Spreading an object literal into another object literal is unnecessary.
> 1 │ const object = { first, ...{ second } };
│ ^^^^^^^^^^^^^
2 │
ℹ Write the properties directly in the surrounding object.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the spread and the curly braces.
1 │ const·object·=·{·first,·...{·second·}·};
│ ----- --
foo(first, ...[second]);code-block.js:1:12 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Spreading an array literal into the arguments of a call is unnecessary.
> 1 │ foo(first, ...[second]);
│ ^^^^^^^^^^^
2 │
ℹ Pass the elements directly as arguments.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the spread and the square brackets.
1 │ foo(first,·...[second]);
│ ---- -
Object.assign(target, { ...source });code-block.js:1:23 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ This object only copies the properties of other values before Object.assign() copies them again.
> 1 │ Object.assign(target, { ...source });
│ ^^^^^^^^^^^^^
2 │
ℹ Object.assign() copies the properties of each argument, so pass the spread values as separate arguments.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Pass the spread values as separate arguments.
1 │ Object.assign(target,·{·...source·});
│ ----- -
const set = new Set(...items);code-block.js:1:21 lint/nursery/noUselessSpread ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Spreading into new Set() passes each item as a separate argument.
> 1 │ const set = new Set(...items);
│ ^^^^^^^^
2 │
ℹ The constructor reads a single iterable, so only the first item is used.
ℹ Pass the iterable directly, without spreading it.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
const set = new Set([...items]);code-block.js:1:21 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Converting this iterable to an array is unnecessary, because new Set() accepts any iterable.
> 1 │ const set = new Set([...items]);
│ ^^^^^^^^^^
2 │
ℹ Pass the iterable directly to avoid copying every item.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Pass the iterable directly.
1 │ const·set·=·new·Set([...items]);
│ ---- -
for (const item of [...items]) {}code-block.js:1:20 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ Converting this iterable to an array is unnecessary, because for...of accepts any iterable.
> 1 │ for (const item of [...items]) {}
│ ^^^^^^^^^^
2 │
ℹ Pass the iterable directly to avoid copying every item.
ℹ Keep the copy if the loop changes the iterable while it runs.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Pass the iterable directly.
1 │ for·(const·item·of·[...items])·{}
│ ---- -
const keys = [...Object.keys(object)];code-block.js:1:14 lint/nursery/noUselessSpread FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ℹ This spread copies an array that was just created.
> 1 │ const keys = [...Object.keys(object)];
│ ^^^^^^^^^^^^^^^^^^^^^^^^
2 │
ℹ The spread value is already a new array, so it can be used directly.
ℹ This rule belongs to the nursery group, which means it is not yet stable and may change in the future. Visit https://biomejs.dev/linter/#nursery for more information.
ℹ Unsafe fix: Remove the copy.
1 │ const·keys·=·[...Object.keys(object)];
│ ---- -
const array = [first, ...rest];const object = { first, ...rest };foo(first, ...rest);Object.assign(target, source);const set = new Set(items);for (const item of items) {}const keys = Object.keys(object);const copy = [...array];Related links
Section titled “Related links”Copyright (c) 2023-present Biome Developers and Contributors.