@babel/plugin-proposal-optional-chaining

NOTE: This plugin is included in @babel/preset-env, in ES2020

Example

Accessing deeply nested properties

  1. const obj = {
  2. foo: {
  3. bar: {
  4. baz: 42,
  5. },
  6. },
  7. };
  8. const baz = obj?.foo?.bar?.baz; // 42
  9. const safe = obj?.qux?.baz; // undefined
  10. // Optional chaining and normal chaining can be intermixed
  11. obj?.foo.bar?.baz; // Only access `foo` if `obj` exists, and `baz` if
  12. // `bar` exists
  13. // Example usage with bracket notation:
  14. obj?.["foo"]?.bar?.baz; // 42

Calling deeply nested functions

  1. const obj = {
  2. foo: {
  3. bar: {
  4. baz() {
  5. return 42;
  6. },
  7. },
  8. },
  9. };
  10. const baz = obj?.foo?.bar?.baz(); // 42
  11. const safe = obj?.qux?.baz(); // undefined
  12. const safe2 = obj?.foo.bar.qux?.(); // undefined
  13. const willThrow = obj?.foo.bar.qux(); // Error: not a function
  14. // Top function can be called directly, too.
  15. function test() {
  16. return 42;
  17. }
  18. test?.(); // 42
  19. exists?.(); // undefined

Constructing deeply nested classes

  1. const obj = {
  2. foo: {
  3. bar: {
  4. baz: class {
  5. },
  6. },
  7. },
  8. };
  9. const baz = new obj?.foo?.bar?.baz(); // baz instance
  10. const safe = new obj?.qux?.baz(); // undefined
  11. const safe2 = new obj?.foo.bar.qux?.(); // undefined
  12. const willThrow = new obj?.foo.bar.qux(); // Error: not a constructor
  13. // Top classes can be called directly, too.
  14. class Test {
  15. }
  16. new Test?.(); // test instance
  17. new exists?.(); // undefined

Deleting deeply nested properties

Added in: v7.8.0

  1. const obj = {
  2. foo: {
  3. bar: {},
  4. },
  5. };
  6. const ret = delete obj?.foo?.bar?.baz; // true

Installation

  1. npm install --save-dev @babel/plugin-proposal-optional-chaining

Usage

  1. {
  2. "plugins": ["@babel/plugin-proposal-optional-chaining"]
  3. }

Via CLI

  1. babel --plugins @babel/plugin-proposal-optional-chaining script.js

Via Node API

  1. require("@babel/core").transformSync("code", {
  2. plugins: ["@babel/plugin-proposal-optional-chaining"],
  3. });

Options

loose

boolean, defaults to false.

When true, this transform will pretend document.all does not exist, and perform loose equality checks with null instead of strict equality checks against both null and undefined.

⚠️ Consider migrating to the top level noDocumentAll assumption.

  1. // babel.config.json
  2. {
  3. "assumptions": {
  4. "noDocumentAll": true
  5. }
  6. }

Example

In

  1. foo?.bar;

Out (noDocumentAll === true)

  1. foo == null ? void 0 : foo.bar;

Out (noDocumentAll === false)

  1. foo === null || foo === void 0 ? void 0 : foo.bar;

You can read more about configuring plugin options here

References