What is Optional chaining - ?.

avatar

Borislav Hadzhiev

Fri Feb 26 20212 min read

Optional chaining helps us write code where TypeScript can immediately stop running some expressions if we run into null or undefined

Theory and differences between && and ?. #

Optional chaining is a neat syntax that allows us to short circuit an expression if we encounter a null or undefined value.

You have probably written code like:

const employeeName = employee && employee.name;

We are just checking if the employee value is truthy, if it is then we access it's name property.

So if employee is any truthy value, like a non-empty string, an object, array, etc we would assign the name property to the employeeName variable.

If employee is a falsy value - like null, undefined, 0, '', etc - then employeeName would be assigned the falsy value and the part after employee would not be evaluated.

In typescript you could do:

const employeeName = employee?.name;

In the typescript case - we're saying if employee is not null or undefined access it's name property and assign its value to the employeeName variable.

In the case employee is null or undefined - stop evaluation immediately and return undefined.

You can see how the && and ?. operators are slightly different.

In the case of && we might get any of the falsy values returned from the expression, in the case of ?. we can only get undefined if the value preceding the operator is null or undefined.

Also the && operator is a broader check that covers all falsy values as opposed to ?. which only covers null and undefined in the check, so:

  • && - if (falsy) {return falsy}
// a is '', short circuits because '' is falsy
const a = '' && 'hello';
  • && - if (truthy) {return complete evaluation of expression}
// b is '', completes evaluation because 'hello' is truthy
const b = 'hello' && '';
  • ?. - if (null || undefined) {return undefined}
let c;
// logs undefined
console.log(c?.test);

let d = null;
// logs undefined
console.log(d?.test);
  • ?. - if (falsy && !(null || undefined)) {return complete evaluation of expression}
const e = '';
// logs 'hello'
console.log(e?.concat('hello'));
  • ?. - if (truty) {return complete evaluation of expression}
// logs 'HELLO'
console.log('hello'?.toUpperCase());

If isArray or string - access element at index - else return undefined #

Get the first element of the array if we have an array, otherwise return undefined:

With a valid array:

const arr1 = ['hello'];
// logs 'hello'
console.log(arr1?.[0]);

Without a valid array:

const notarr1 = '';
// logs undefined
console.log(notarr1?.[0]);

With a truthy string:

const notarr2 = 'hello';
// logs 'h'
console.log(notarr2?.[0]);

With a true boolean value:

const notarr3 = true;
// logs undefined
console.log(notarr3?.[0]);

Call expression if they're not null or undefined #

Only call a function if it's value is not null or undefined:

function maybeLog(logger?: (message: string) => void) {
  // only call logger if it is NOT undefined or null
  logger?.('Hello World!');
}

// doesn't call logger, because it is undefined
maybeLog();

// calls logger and logs 'Hello World!'
maybeLog(message => console.log(message));

End #

The elegant ?. helps us short circuit an expression if we encounter null or undefined values. Using a very compact syntax, we can conditionally access object or array elements and call functions.

As of the 26th of February 2021, the ?. operator is supported by about 85.66% of browsers - caniuse.com.

Join my newsletter

I'll send you 1 email a week with links to all of the articles I've written that week

Buy Me A Coffee