DEV Community

Cover image for Spreading arrays in a resilient way using JavaScript/TypeScript
James Won
James Won

Posted on

Spreading arrays in a resilient way using JavaScript/TypeScript

Spreading is a really handy technique that we JavaScript developers use daily.

Some common usages are:

  • When constructing a new array using the existing array items immutably.
  • When updating or adding items to an array.

We see code like the following often:

const originalArray = [a: {count: 1}, b: {count: 2}, c: {count: 3}]

const newArray = [...originalArray, a: { count: 10}]
Enter fullscreen mode Exit fullscreen mode

Perils of spreading in JavaScript

But it can be fraught with peril when the spread array can be undefined.

Just like with destructuring undefined values, spreading undefined values can be the source of unexpected bugs.

For example examine the code below:

const originalArray = couldBeStringArrayOrUndefined()

const newArray = [...originalArray]
Enter fullscreen mode Exit fullscreen mode

Perils in TypeScript

This same code is further complicated in TypeScript. You will be faced with an error

const originalArray = couldBeStringArrayOrUndefined()

const newArray: string[] = [...originalArray]

Type 'string[] | undefined' must have a '[Symbol.iterator]()' method that returns an iterator.
Enter fullscreen mode Exit fullscreen mode

Solution

The solution is quite simple.

If you know the value could be undefined add an OR empty array.

So for the above code:

// In Vanilla JS
const newArray = [...originalArray || []]

// In TypeScript
const newArray: string[] = [...originalArray || []]
Enter fullscreen mode Exit fullscreen mode

This solution makes intuitive sense, as this code is simply specifying that if the spread array is undefined an empty array will be spread (and thus no items spread).

Caveat

This solution comes with the caveat that wherever possible it is better to make sure an undefined value is handled further up the chain.

For example if your undefined value can come from an asynchronous call, it might be better to explicitly get your promise to resolve to an empty array [].

This will have the same effect as the solution above, but also give you the confidence of being able to test the value being added in.

But this isn't always possible, so don't feel bad if you have to resort to the ...spreadArray || [] combo when needed.

Takeaways

  • Using the spread operator is great!
  • But be careful of spreading undefined values.
  • Use the simple ...spreadArray || [] combo to make your code resilient to undefined values!

Top comments (0)