loading...

Optional Chaining — Using it already

devcer profile image Santosh Viswanatham Originally published at Medium on ・4 min read

Optional Chaining — Using it already

Photo by Florian Weichelt on Unsplash

Typescript website defines Optional Chaining as

At its core, optional chaining lets us write code where Typescript can immediately stop running some expressions if we run into a null or undefined.

As JavaScript Developers we often get to work with deeply nested JSON objects, If the data is from a REST API then you are more likely depend on the Backend to ensure your response is in the format you are expecting, else we run into errors during runtime while executing expressions on those objects.

consider the following example

const person = {
  name: {
    first: {
      text: "Santosh"
    }
  },
  pets: ['cat', 'dog']
}

console.log(person.name.first.text.length); // logs the length of firstname
console.log(person.name.last.text.length); // throws an Error

Here in the second log, person.name.last is undefined and the expression tries to evaluate the text property of undefined which throws an error.

To handle this case I usually do

console.log(person && person.name && 
    person.name.last && 
    person.name.last.text && 
    person.name.last.text.length); // doesn't throw any error. logs undefined instead

I check the child property before accessing it, yet it is kind of messy. With optional chaining coming into the picture, we can do this instead

console.log(person?.name?.last?.text.length); // logs undefined

Pretty clean and simple, right? ⛓

You can use this for arrays and functions as well.

console.log(person.pets[3]); // throws an Error

with optional chaining, you can do a safe-check

console.log(person?.pets?.[3]); // doesn't throw an error, logs undefined instead

Enabling Optional Chaining in Chrome 79+

As per MDN, only Chrome 79+ and Opera 65+ have Experimental support for Optional chaining which has to be first enabled on the browser.

In Chrome

  • open the URL chrome://flags in your chrome browser
  • Enable Experimental JavaScript flag from the available Experiments

Current Status

  • Optional Chaining proposal has reached Stage 4(as of today, Jan 2020) of the TC39 process. 🙏

The active status of the proposal can be found in this repo here.

Configuring with Babel

  • Babel enabled us to use next-gen JavaScript today, and there is already a babel plugin that you can install to start using Optional Chaining.

You can find the installation instructions here.

Internally Babel transpiles the following code

console.log(person?.name?.last?.text.length);

to

var \_person$name, \_person$name$last;

console.log(person === null
  || person === void 0 ? void 0 : (\_person$name = person.name) === null
  || \_person$name === void 0 ? void 0 : (\_person$name$last = \_person$name.last) === null
  || \_person$name$last === void 0 ? void 0 : \_person$name$last.text.length);

If you are thinking about what the hell is void 0 then I recommend you to go through this article. It basically evaluates to undefined . Now, look at the above code again to understand it.

At any point, if the nested property is either null or undefined the expression evaluates to undefined

Optional Chaining in Typescript

I’m glad everyone is moving forward with optional chaining much quicker than expected. Typescript 3.7 now has support for Optional Chaining. 🙌

You can find the release notes here.

Let's see how the TypeScript code of Optional chaining transpiles to JavaScript.

console.log(person?.name?.last?.text.length);

I was using the tsc command-line tool to compile the above TS Code and the transpiled code was

var \_a, \_b, \_c;
console.log((\_c = (\_b = (\_a = person) === null 
  || \_a === void 0 ? void 0 : \_a.name) === null 
  || \_b === void 0 ? void 0 : \_b.last) === null 
  || \_c === void 0 ? void 0 : \_c.text.length);

It is almost the same as what we saw in the babel transpiled code. The object person is being checked at every level in its nested structure to see if the next key in that expression exists, else it returns undefined rather than throwing out an error.

Optional Chaining in VS Code

If you were using an older version of VS Code as your editor while running a few of the above code samples then your IDE would have yelled at you with errors.

Good news, VS Code 1.41 version now supports Optional Chaining. Thanks to Typescript 3.7(that’s what they said). 💪 You can find more info about the release here.

It is clear that we already have enough support to start using Optional Chaining in our projects. So, update your IDEs, update your TS Version and configure additional plugins to use it now. Let's throw a little fewer runtime errors with our expressions.

Posted on by:

devcer profile

Santosh Viswanatham

@devcer

An open web philanthropist | Mozilla Tech Speaker | Senior Development Engineer at Pramati

Discussion

markdown guide
 

You can use optional chaining today in every browser:

(((person||{}).name||{}).last||{}).text