Optional chaining and the null coalescing operator are game-changers in TypeScript 3.7
Tags: typescript, javascript, webdev
Published: 2019-10-17 00:03:43

---
title: Optional chaining and the null coalescing operator are game-changers in TypeScript 3.7
published: true
tags: typescript,javascript,webdev 
canonical_url: https://blog.logrocket.com/new-in-typescript-3-7/
cover_image: https://thepracticaldev.s3.amazonaws.com/i/7kqhkzi8x2jwk6755pjg.png
---
**Written by [Paul Cowan](https://blog.logrocket.com/author/paulcowan/)**✏️

I think the TypeScript 3.7 release is enormous. I have waited a very, very long time to have optional chaining having tasted it briefly on a C# contract a few years ago.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## What problem does it solve?

One of the most significant pain points that most of us have in the JavaScript/TypeScript world is continuously checking variables or expressions for `null` or `undefined`. The example below is TypeScript 3.7 and illustrates what a game-changer this release is. We can finally drastically stop the amount of nonsense code we have to write with the new feature.

```jsx
class Student {
  constructor(public name: string) {}

  discipline?: Discipline;
  
  printDetails() {
    return `
      name: ${this.name}
      discipline: this.discipline?.name || 'Not set';
    `;
  }
}

class Discipline {
  student?: Student;

  constructor(public name: string) { }
}

class College {
  constructor(public name: string) { }

  disciplines?: Discipline[];
}

class City {
  constructor(public name: string) { }

  college?: College;
}


class University {
  constructor(public name: string) { }

  city?: City;

  get college(): College | undefined {
    return this?.city?.college;
  }

  addDisciplines(...disciplines: Discipline[]) {
    if (!this.city?.college?.disciplines) {
      return;
    }

    this.city.college.disciplines.push(...disciplines)
  }
}

const university = new University("Queen's University Belfast");
const city = new City("Belfast");
const computerScience = new Discipline("Computer Science");
const economics = new Discipline("Economics");
const college = new College("Da College");
const student = new Student("Brian Cant");

university.city = city;
university.city.college;

university.addDisciplines(computerScience, economics);

const firstStudent = university.city?.college?.disciplines?.[0]?.student; // Student | undefined

console.log(firstStudent?.printDetails())
```

[Here is a playground](http://www.typescriptlang.org/play/?ts=3.7-Beta&ssl=1&ssc=1&pln=70&pc=1#code/MYGwhgzhAEDKAuBXAJgUwHb2gbwLAChppgB7dCeAJ0WHhMoAoAHRAIxAEthp0wBbVAC5oFSh3QBzAJQ4AvgQJFkHCMA5NO6VAH5hAERVqN41AG4FhaIuhMxmPanhgOICAxl5LRSo8SV00AAG1kREvALCACTY8AAWKgB04ajyXqHKquqaQtBxiRlG2dpJ-KjQAD7l0ADkAHIkWBCO1eZpga1EqakEoJAwBpnGWjjWFCgY8LpwSGiYrdak5FQ0dIws7Fw8pcKi4tI40F0WvVDQAMIkICCoEmWeRIuiK-TMbJzcyTtUex6HFkqGLImCBTAaFEwAbQAuq1uvgTjAzhx4ABPEaWR7LWgvdbvLYRETfSS-OEPS7XW5TC5XG5mAhwnrgU4AVXQHAAbqhKBBkWj7sQyE9sWs3ptPoS7PtsH98AteVTefNLLcsKQabd3MJqRSylVEOg0AAzEzIdGhaA+JD+XLxEEJNSo4pqnUdGXWMDIZBgoFaNwJf0FH2oCD6QFDVDQjwhaAcQ3QBgAQjyEHt8vt5NpxUD4YgUbS3l8-ldnX+oWTqdR6fVqAS2eyKZYEFiDH9tbD9ak1gZ+DhmOg+o5XJ5qOgAF4eKgAO7QVmD7m8hgAIgAiohUBhqjBZ5z5yOAEKoECGyDwRdSVp9h1o8daadI1FLg9Hk9ni+C1UkPgseBc2BqDDAGUN5TtA3rhkuFxfogP6UHA-7oIBr49O+0CoIsn5cDAwHTmB2RLgAouhfCYUh8Ioc6tJjhOd4Zhqi56GA5y0agpF9mMsxYNh0zjJgj5iGAARnAJp7nhYA47sOKIVtexCKgQ4lDry0lVi6YlshJSkel67bAgwpBQTBf4cABqAADSoURmGibKZFLNAxrcvACA8Zx-bqYplZXk6zFZjpvrFBCAAMULFOxEymNAAD0kXcRxFRuUaJrHIKlw1iAJASAwDkUM5HHFLY4jwA4TguG4UidjZQA) with a working example of the above code snippet.

**Line 1** contains a `Student` class definition which contains an optional `discipline` property that might have an `undefined` or `null` value. A `printDetails` method exists on **line 6** that involves access with an optional property.

```jsx
printDetails() {
  return `
    name: ${this.name}
    discipline: this.discipline?.name || 'Not set';
  `;
}
```

You specify optional chaining by placing a `?` question mark after the optional property value on which you wish to call the property, method or even subscript (more on this later) to force the unwrapping of its value. If during the unwrapping of the property or method a `null` value or an `undefined` value is found, `undefined` is returned. `undefined` is always returned no matter if the underlying value is `null` or `undefined`.

Below is some of the horrible code we would tediously write before this exquisite release.

```jsx
printDetails() {
  return `
    name: ${this.name}
    discipline: this.discipline && this.discipline.name ? this.discipline.name : 'Not set';
  `;
}
```

Where optional chaining glistens is when dealing with deeply nested objects on **line 3** of the code example below or **line 63** of the first code example:

```jsx
university.addDisciplines(computerScience, economics);

const firstStudent = university.city?.college?.disciplines?.[0]?.student; // Student | undefined

console.log(firstStudent?.printDetails())
```

We would previously have to do some pretty disgusting things to access such a deep hierarchy, but we can now optionally chain our way to a much better existence with TypeScript 3.7.

## Accessing subscripts through optional chaining

You can use optional chaining to try to retrieve a value from a subscript on an optional value and to check whether that subscript call is successful.

```jsx
const firstStudent = university.city?.college?.disciplines?.[0]?.student;
```

Instances of the `Discipline` class can have an array of students. When you access a subscript on an optional value through optional chaining, you place the question mark _before_ the subscript’s brackets, not after. The optional chaining question mark always follows immediately after the part of the expression that is optional.

I think this is massive, we will write significantly less code that checks for the existence of things. I cannot contain my excitement at this release.

## The null coalescing operator

Another feature I have experienced previously in C# is the null coalescing operator (`??`) that simplifies checking for null or undefined values.

```jsx
const a: number | null = null;
const b = a ?? 42;

console.log(b);  // 42
```

### What about `||`?

The first time I saw this in TypeScript, I shouted ‘what about `||`?’ Below is the same example with the same result.

```jsx
const a: number | null = null;
const b = a || 42;

console.log(b);  // 42
```

Where this example falls apart is with JavaScript’s truthy and falsy shenanigans.

```jsx
const a: number | null = 0;
const b = a || 42;

console.log(b);  // 42
```

Unfortunately `0` returns false when used in an expression with JavaScript so `42` will get to the console which is incorrect.

The coalescing operator comes to the rescue in this situation.

```jsx
const a: number | null = 0;
const b = a ?? 42;

console.log(b);  // 0
```

I am going to stop using the shortcircuit or `||` operator when TypeScript 3.7 gets released and instead use the beautiful `??` operator.

## Game changed

I have waited a long time for these changes, and I think the [TypeScript official](https://devblogs.microsoft.com/typescript/announcing-typescript-3-7-beta/) announcement does its usual job of underselling the great new features.

I also hate the code examples they use:

```jsx
// Before
if (foo && foo.bar && foo.bar.baz) {
    // ...
}

// After-ish
if (foo?.bar?.baz) {
    // ...
}
```

I think this illustrates the disconnect between the real world and the TypeScript developers. `foo`, `bar` ,and `baz` are just about the worst examples to use for anything. I cannot think of anything tangible with these made up properties.

I think there should be much more made of this release. It will make writing TypeScript significantly less annoying.

Please leave feedback on the comments below.
* * * 
**Editor's note:** Seeing something wrong with this post? You can find the correct version [here](https://blog.logrocket.com/new-in-typescript-3-7/).

## Plug: [LogRocket](https://logrocket.com/signup/), a DVR for web apps
 
![LogRocket Dashboard Free Trial Banner](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/1d0cd-1s_rmyo6nbrasp-xtvbaxfg.png?resize=1200%2C677&ssl=1)
 
[LogRocket](https://logrocket.com/signup/) is a frontend logging tool that lets you replay problems as if they happened in your own browser. Instead of guessing why errors happen, or asking users for screenshots and log dumps, LogRocket lets you replay the session to quickly understand what went wrong. It works perfectly with any app, regardless of framework, and has plugins to log additional context from Redux, Vuex, and @ngrx/store.
 
In addition to logging Redux actions and state, LogRocket records console logs, JavaScript errors, stacktraces, network requests/responses with headers + bodies, browser metadata, and custom logs. It also instruments the DOM to record the HTML and CSS on the page, recreating pixel-perfect videos of even the most complex single-page apps.
 
[Try it for free](https://logrocket.com/signup/).
* * *
The post [Optional chaining and the null coalescing operator are game-changers in TypeScript 3.7](https://blog.logrocket.com/new-in-typescript-3-7/) appeared first on [LogRocket Blog](https://blog.logrocket.com).