Optional Chaining — Using it already
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.
Top comments (2)
You can use optional chaining today in every browser:
(((person||{}).name||{}).last||{}).text
Great trick