Optional Chaining in TypeScript

Optional Chaining in TypeScript

In this article, we explain about Optional Chaining in TypeScript.

YouTube Video

Optional Chaining in TypeScript

Optional chaining in TypeScript is a useful feature for accessing properties of deeply nested objects or arrays. This feature prevents errors when accessing nonexistent properties, allowing you to write concise and readable code.

What is Optional Chaining?

The optional chaining operator (?.) returns undefined when accessing an object property or method that doesn't exist. This allows the code to continue running without throwing an error if the property doesn't exist.

For example, when accessing properties of a nested object as shown below, an error occurs if the property does not exist using the usual method.

Example

 1interface User {
 2    name?: string;
 3    address?: {
 4        city?: string;
 5        postalCode?: string;
 6    };
 7}
 8
 9const user: User = {
10    name: 'Alice'
11};
12
13// Normal access
14console.log(user.address.postalCode); // Error: Cannot read property 'postalCode' of undefined
  • In this case, an error will occur if address does not exist. Optional chaining can be used to prevent this.

Example using optional chaining

 1interface User {
 2    name?: string;
 3    address?: {
 4        city?: string;
 5        postalCode?: string;
 6    };
 7}
 8
 9const user: User = {
10    name: 'Alice'
11};
12
13console.log(user.address?.postalCode); // undefined
  • Using optional chaining avoids errors and returns undefined instead when properties do not exist.

How to Use Optional Chaining

Optional chaining can be used in various scenarios, such as property access, function calls, and array access. We will explain how to use each of these.

Accessing Properties

You can safely access nested properties of objects.

 1interface Company {
 2    name: string;
 3    location?: {
 4        city?: string;
 5        country?: string;
 6    };
 7}
 8
 9const company: Company = {
10    name: 'Tech Corp',
11    location: {
12        city: 'New York'
13    }
14};
15
16console.log(company.location?.city); // 'New York'
17console.log(company.location?.country); // undefined

This code uses optional chaining to access the city and country properties only if the location property exists on the company object.

Function Calls

Optional chaining can also check for the existence of a function before calling it.

 1interface User {
 2    name?: string;
 3    greet?: () => void;
 4}
 5
 6const user: User = {
 7    name: 'Bob',
 8    // greet is undefined
 9};
10
11// Check if the function exists before calling it
12user.greet?.(); // The call is not made, and no error occurs

This code uses optional chaining to safely invoke the greet function only if it exists. No error occurs even if the function is undefined.

Array Access

Optional chaining can be applied to arrays to check if elements exist.

 1interface Team {
 2    members?: string[];
 3}
 4
 5const team: Team = {
 6    members: ['Alice', 'Bob', 'Charlie']
 7};
 8
 9console.log(team.members?.[0]); // 'Alice'
10console.log(team.members?.[5]); // undefined

This code accesses array elements only if team.members exists, returning the value for existing indexes and undefined for non-existent ones.

Optional Chaining and the Nullish Coalescing Operator

Optional chaining returns undefined, but sometimes this is not sufficient. In this case, the nullish coalescing operator (??), introduced in TypeScript 3.7, can be used to provide default values for null or undefined.

 1interface User {
 2    name?: string;
 3    address?: {
 4        city?: string;
 5        postalCode?: string;
 6    };
 7}
 8
 9const user: User = {
10    name: 'Carol'
11};
12
13// Use 'Unknown' as the default value if name does not exist
14const userName = user.name ?? 'Unknown';
15
16console.log(userName); // 'Carol'

When combined with optional chaining, you can write even more flexible code.

1console.log(user.address?.postalCode ?? 'Not provided'); // 'Not provided'

Cautions When Using Optional Chaining

When using optional chaining, it's important to keep the following points in mind:.

  • Unnecessary use of optional chaining

    • Using optional chaining on properties or methods that are guaranteed to exist can make your code unnecessarily verbose. It's best used only when the existence of the accessed target is uncertain.
  • Typographical errors

    • Overusing optional chaining can make it harder to notice typographical errors that result in accessing unintended properties. Perform proper type checks and use it cautiously.

Code summary

 1interface User {
 2    name?: string;
 3    address?: {
 4        city?: string;
 5        postalCode?: string;
 6    };
 7}
 8
 9const user: User = {
10    name: 'Alice',
11    address: {
12        city: 'Tokyo'
13    }
14};
15
16// Example of optional chaining
17console.log(user.address?.city); // 'Tokyo'
18console.log(user.address?.postalCode); // undefined
19
20// Using optional chaining combined with nullish coalescing
21console.log(user.address?.postalCode ?? 'Not provided'); // 'Not provided'

Summary

Optional chaining in TypeScript provides concise code while avoiding errors when accessing deeply nested objects or arrays. In addition, combining it with the nullish coalescing operator allows you to set default values and create more flexible logic. When used appropriately, it can significantly improve code safety and readability.

You can follow along with the above article using Visual Studio Code on our YouTube channel. Please also check out the YouTube channel.

YouTube Video