Optional Chaining - patrickcole/learning GitHub Wiki

Optional Chaining

Status

  • Available in ES2020 (ES11) specification
  • Available in TypeScript v3.7

Notes

  • also known as the "safe navigation operator" in other languages
  • replaces the practice of using typeof validation and hasOwnProperty
  • if property is not found, the result will now return undefined instead of breaking the execution of code
  • good use cases for configuration objects, JSON data returned from APIs or optional properties

Syntax

obj?.prop         // optional static property access
obj?.[exp]        // optional dynamic property access
arr?.[exp]        // arrays can use dynamic property access as well
func?.(...args)   // optional function or method call
const user = {
  name: `Patrick`,
  country: `USA`
}

console.log(user.contact?.email); // => undefined
console.log(user.contact.email); // => TypeError: Cannot read property 'email' of Object
  • can also be used inside conditional statements, which can be helpful for dealing for cases when properties aren't found
if ( user.contact?.email ) {
  // User has contact details AND an email address
  // so an email can be sent;
} else {
  // User does not have contact details, so no email;
}

// a real practical example:
if ( user.contact?.email ) {

  // sendEmail is a custom function:
  sendEmail(user.contact.email);
}

Here's a great example of dealing with potential complex objects effectively from Adrian Legaspi:

console.log(lang?.en?.words?.rudeWords?.['a bad word'])

If any of those properties are not found under the lang object, it will return undefined.

Use in Methods / Functions

Useful for establishing methods that will execute once the property has been added:

console.log( user?.data?.map(item => item.title) ); // => undefined

// however, we add data to the user object with some objects:
user.data = [ { title: "A" }, { title: "B" } ];

// now re-running the call:
console.log( user?.data?.map(item => item.title) );
// => Array ["A", "B"]

Example: Check For An Array Index

  • we often rely on an array containing at least one item, now we can check in our optional chaining statement rather than a dedicated if-statement
const getLeadingActor = movie => movie.actors?.[0]?.name;

Notice how it checks for at least one item in the 0 index AND if that object has a name property

Example: Combine with Nullish Coalescing To Provide Default

Taking the previous example, a default value can be provided if any of the expected properties return undefined:

const getLeadingActor = movie => movie.actors?.[0]?.name ?? `Unknown Actor`;

Sources