Optional chaining in JavaScript

Published March 23, 2021

The optional chaining operator ?. is for optional property access. Optional chaining allows us to write code that will immediately stop running some expressions if a null or undefined is found.

The optional chaining operator ?. is available in TypeScript as of version 3.7.

Cannot read property of undefined

Consider the following example demonstrating object property access on an undefined object.

let user;
const name = user.firstName;

This code will throw a JavaScript error that will say "Cannot read property 'firstName' of undefined." Since user is undefined, no properties can be accessed from the user object. The optional chaining operator helps us to avoid this error during object property access.

Optional chaining to the rescue

Let's re-visit this same example, but this time with the optional chaining operator.

const name = user?.firstName;

When user is defined, user?.firstName will be computed and firstName will be accessed from the user object. However, when user is null or undefined, the optional chaining operator will stop execution and just return undefined as the name.

const user = undefined;
const name = user?.firstName;
console.log(name); // undefined

const user = { firstName: 'John', lastName: 'Smith' };
const name = user?.firstName;
console.log(name); // John

How optional chaining works

Consider the following example to see the same line of code with and without the optional chaining operator to gain a better understanding of how it works.

// with optional chaining
const name = user?.firstName;
// without optional chaining
const name = (user === null || user === undefined) ? undefined : user.firstName;

Left side checks only

The optional chaining operator will only check if the value on the left of it is null or undefined. It will not check any properties to the right of it.

const user = {};
const zip = user?.address.zip;
console.log(zip);

This code block throws an error saying "Cannot read property 'zip' of undefined." This is because there is no address property in the user object. Thus, it is undefined and a zip property cannot be accessed from undefined. The optional chaining operator only helped us with null and undefined checks on the user object appearing to the left of it.

Nested object property access

The optional chaining operator can be used several nested levels deep.

const user = {};
const zip = user?.address?.zip;
console.log(zip); // undefined

This example will not throw the error we saw in the previous example because we have added the optional chaining operator to the address property. If address is found to be null or undefined, then undefined is returned without throwing an error.