Proposal: Nullish Conditional Inclusion Operator (???)

Hey all,
I was recently lamenting the the awkwardness of conditionally including values in arrays and thought, "what if you could spread a single value into an array?". Clearly you can do it the with [1, ...(x? [x] : [], 2] but it's noisy. I thought it'd be great to build on ?? and ... to make this very common pattern nicer.

Here's my proposal (with working albeit hacky reference implementation)

I'd love to hear any feedback you have. Also if any members are interested in championing this modest sugar.

:folded_hands:

Related: Conditionally add elements to declaratively defined arrays

3 Likes

You already can with .concat, no syntax required.

@ljharb
I don't understand how .concat helps. Seems like you'd still be doing essentially the same thing that the declarative code in my motivation statement is:

[].concat(xs, x != null ? x : [], ys)

Which is about as noisy--if not more--than the common idiom using spreads:

[...xs, ...(x != null ? x : []), ...ys)

My proposal isn’t about enabling something that’s impossible today, it’s about making a very common conditional-inclusion pattern more declarative and readable inside array literals. Just like how ?? and ?. improved expressiveness without adding new capability.

You'd do [].concat(xs, x ?? []) or xs.concat(x ?? []). Syntax has a very high cost, and both of those seem pretty straightforward, and are common JS idioms stretching back decades.

Using just .concat(x ?? []) might not do what you want for a single element x, it requires knowing that x is not concat-spreadable. So you have to use x ? [x] : [] - regardless whether within spread syntax or with .concat. And while this indeed is a straightforward idiom, it is also a really common problem, and might be worth investigating.

As for bikeshedding syntax, I'd imagine it to look like a postfix operator ?, which makes an array element optional:

x = [a, b, c ?, d, e] // [a, b, ...(tmp => tmp != null ? [tmp] : [])(c), d, e]
x = [a, b, ...c ?, d, e] // [a, b, ...c ?? [], d, e]

Nothings concat spreadable in practice that you wouldn’t want spread tho, so it’s fine.

Only if you know what concrete data you're working with. If you're writing a generic function that should be able to work with any user-supplied data type, all you know is that you never want to spread the value, so you cannot pass it to concat. The user might want to build an array of arrays after all.

2 Likes