Skip to content

noConfusingArraySplice (JavaScript)

Language JavaScript (and super languages)
biome.json
{
"linter": {
"rules": {
"nursery": {
"noConfusingArraySplice": "error"
}
}
}
}

Disallow splice() and toSpliced() calls that are harder to read than the operation they perform.

A splice() call that removes one element and adds one element back replaces a single element. Assigning to the index, as in array[index] = element, says the same thing more directly. In the same way, toSpliced() with these arguments creates a copy of the array with one element replaced, which is what with() does.

A splice() or toSpliced() call that inserts at index -1 without removing anything adds the elements before the last element. When the array is empty, it adds them at the start instead. Readers can easily mistake this for adding at the end, so it is clearer to work out the index explicitly.

The rule ignores calls with spread arguments (...), and calls that use optional chaining (?.) to read or call the method, such as array?.splice(index, 1, element) or array.splice?.(index, 1, element).

The fixes are unsafe, because the replacements don’t behave the same for every index:

  • splice() and toSpliced() count a negative index from the end of the array, while array[-1] = element creates a property named -1.
  • splice() and toSpliced() add the element at the end when the index is past the end, while an assignment leaves empty slots before the new element, and with() throws an error.
  • splice() returns the removed elements, while an assignment returns the new element.
array.splice(index, 1, element);
code-block.js:1:1 lint/nursery/noConfusingArraySplice  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This splice() call replaces a single element.

> 1 │ array.splice(index, 1, element);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ Readers have to work out what each argument means to understand the call.

ℹ Assign to the index instead, as in array[index] = element.

ℹ 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: Assign to the index instead.

1 │ - array.splice(index,·1,·element);
1 │ + array[index]·=·element;
2 2 │

const result = array.toSpliced(index, 1, element);
code-block.js:1:16 lint/nursery/noConfusingArraySplice  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This toSpliced() call replaces a single element.

> 1 │ const result = array.toSpliced(index, 1, element);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ Readers have to work out what each argument means to understand the call.

ℹ Use with() instead, as in array.with(index, element).

ℹ 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: Use with() instead.

1 │ - const·result·=·array.toSpliced(index,·1,·element);
1 │ + const·result·=·array.with(index,·element);
2 2 │

array.splice(-1, 0, element);
code-block.js:1:1 lint/nursery/noConfusingArraySplice  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This splice() call inserts at index -1.

> 1 │ array.splice(-1, 0, element);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ It inserts before the last element, or at the start when the array is empty. Readers can mistake it for inserting at the end.

ℹ Work out the index explicitly, as in Math.max(array.length - 1, 0).

ℹ 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: Work out the insertion index explicitly.

1 │ array.splice(Math.max(array.length·-·1,·0),·0,·element);
│ ++++++++++++++++++++++ + ++++
const result = array.toSpliced(-1, 0, element);
code-block.js:1:16 lint/nursery/noConfusingArraySplice  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

⚠ This toSpliced() call inserts at index -1.

> 1 │ const result = array.toSpliced(-1, 0, element);
│ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2 │

ℹ It inserts before the last element, or at the start when the array is empty. Readers can mistake it for inserting at the end.

ℹ Work out the index explicitly, as in Math.max(array.length - 1, 0).

ℹ 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: Work out the insertion index explicitly.

1 │ const·result·=·array.toSpliced(Math.max(array.length·-·1,·0),·0,·element);
│ ++++++++++++++++++++++ + ++++
array[index] = element;
const result = array.with(index, element);
const insertionIndex = Math.max(array.length - 1, 0);
array.splice(insertionIndex, 0, element);
array.splice(index, 2, element);
array.splice(-1, 0, element, otherElement);
array?.splice(index, 1, element);