1

Suppose the following:

const arr = [1, 2, 3];
const insertValues = [-1, 0];
const condition = true;

arr.splice(0, 0, condition ? ...insertValues : insertValues);

This throws a syntax error:

Unexpected token '...'

I can get this to work by doing the following:

const arr = [1, 2, 3];
arr.splice(0, 0, ...[-1, 0]);

But this is obviously not what I'd like to do. How can I get the first example to work? I've tried including parentheses where I'd have thought necessary, to no avail.

2
  • ...(condition ? insertValues : [insertValues])? The expression needs to be evaluated to a value to pass to splice, and if you make it e.g. const thing = condition ? ...insertValues : insertValues; it should be clear why what you've written makes no sense. Commented Jan 16, 2024 at 12:40
  • 2
    That's mostly because there is no spread operator. What you have makes about as much sense as conditionally calling a function via fn if (condition) {()} Commented Jan 16, 2024 at 12:40

4 Answers 4

4

It would work if ... were an operator, but it isn't (and can't be), it's primary syntax. Operators can't do what ... does. Operators have to have a single value result, but ... doesn't.

So instead, you need to spread an iterable. You could do that by wrapping insertValues in [] when you want to insert it directly (your falsy operand to the conditional operator):

arr.splice(0, 0, ...(condition ? insertValues : [insertValues]));
// (Or you could use `unshift` if the index will always be 0 and you're never deleting anything)

(That may be what you meant later in your question. It's not an unusual idiom in cases where you want to use something as a series of arguments that may or may not be an iterable.)

Or just use an if/else.

Sign up to request clarification or add additional context in comments.

Comments

1

You can place ... before a conditional operator without parentheses:

const arr = [1, 2, 3];
const insertValues = [-1, 0];
const condition = true;
arr.splice(0, 0, ... condition ? insertValues : [insertValues]);

console.log(arr);

Since ... is a syntax (a syntax operates on results of expressions), operators are evaluated before it, a more explicit example:

console.log([... 'a' + 'b']);

Comments

1

Spread syntax is allowed in a handful of locations. Change your code to:

const arr = [1, 2, 3];
const insertValues = [-1, 0];
const condition = true;

arr.splice(0, 0, ...(condition ? insertValues : [insertValues]));

Or this:

if (condition)
  arr.splice(0, 0, ...insertValues);
else
  arr.splice(0, 0, insertValues);

Comments

0

If you don't want to bother with conditions and just want it work for both a number and an array, here's a solution that might be useful:

const arr = [1, 2, 3];
const insertValues = [-1, 0];
const condition = true;
arr.splice(0, 0, ...[insertValues].flat());

This is based on assumption that the intention was condition ? ...number[] : number

4 Comments

That has different semantics than the code OP has. The code in the question would either add two values -1 and 0 or one value - the array [-1, 0]. This will just always add two values regardless of what condition resolves to.
For what I understand, OP may just want to either pass a single number or spread an array of number as properties. This could work if that's the case, otherwise it won't work if OP wants to pass an array as is.
When condition = false the code in the question would insert [-1, 0] as a value. There is no mention they'd want to add a single number. If that is the case, it's not what the question asks or describes. It's solely asking about spread syntax.
The two possible results are (a) the two values -1, 0 prepended to the array (b) one [-1, 0] value prepended to the array.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.