tc39/proposal-optional-chaining

Elvis operator (default return value)

lostpebble opened this issue ยท 4 comments

Hi there, loving this proposal and the happiness it will bring in avoiding TypeErrors. ๐Ÿ™‚

Reading through it though I don't see any mention of a kind of default return value / elvis operator.

To borrow from the Kotlin docs, in the section that deals will null safety (Null Safety: Elvis Operator):

Elvis Operator

When we have a nullable reference r, we can say "if r is not null, use it, otherwise use some non-null value x":

val l = b?.length ?: -1

JavaScript Implementation

To convert this to JavaScript's and this proposal's use-case, we could say:

When we have an undefined reference r, we can say "if r is not undefined, use it, otherwise use some non-null value x":

(and using the first example in this proposal of the street address):

var street = user.address?.street ?: "unknown-street"

Or, perhaps slightly more practical (to make street set as null instead of undefined - for intentionally storing in the database as a null value)

var street = user.address?.street ?: null

And the most practical but very contrived example:

const user = {
  defaultPortionSize: 150,
  definedPortionSizes: {
    potatoes: 200,
    meat: 250,
    carrots: 100,
  },
  getPortionSize(foodType) {
    return this.definedPortionSizes?.[foodType] ?: this.defaultPortionSize;
  }
}

const chipsPortionSize = user.getPortionSize("chips");

// chipsPortionSize = 150

This would cut down on further checks which we would inevitably have to make against the potentially undefined value which is returned from Optional Chaining.

So in this last example, we'd potentially have to do:

let chipsPortionSize = user.getPortionSize("chips");

if (chipsPortionSize === undefined) {
  chipsPortionSize = user.defaultPortionSize;
}

// or (definitely not ideal because we're calling the method twice on "user")

const chipsPortionSize = user.getPortionSize("chips") !== undefined ?  user.getPortionSize("chips") : user.defaultPortionSize;

I feel like this kind of operator would be a great addition to an already great proposal, as it would just round it off to handling these undefined scenarios in a much cleaner way.

Ahh.. I should have expanded my horizons a little:

https://github.com/tc39/proposal-nullish-coalescing

I see that is the operator that is meant to go hand in hand with this.

There is an issue with that though - in that what if a value returns null ? It will return the right-hand side, which is not what you want (because null is still a defined value).

@lostpebble both null and undefined are "empty values" and are often treated the same, both in the language, and in the ecosystem. See tc39/proposal-nullish-coalescing#20 for why it is what you would want.

Hi @ljharb ,

I've actually just responded on that issue about my use case after finding that alternative supporting proposal.

(Note that's not an alternative proposal; optional chaining and nullish coalescing are two distinct parallel proposals that interoperate well with each other)