All Articles

Typescript 3.7 The juicy bits

Typescript playground

Typescript recently released version 3.7 which provides support for anticipated features such as the Optional chaining and Nullish Coalescing operators, along with tasty improvements and features. Here is a summary of the juicy bits.

If you are unfamiliar with typescript, it is basically type-safe javascript. A feature complete version was recently released and along with this release came some of the most requested features. Here is all you need to know about biasedly 😛 the most interesting part of the recent release.

Optional chaining operator

Optional chaining is a long awaited feature. It was proposed almost 3 years ago and is finally officially supported by typescript. When accessing object property values buried deep, there is usually a need to check if the value exist before chaining on. This is also true for the return values some of the standard language APIs as well. The logical operator && has remained a popular way to “short circuit” code execution in conditional statements. Despite its verbosity, it works great in most cases.

declare var accounts;
declare var axiosError;

const didError =
  axiosError && axiosError.response && axiosError.response.status === 404;

const transaction =
  accounts &&
  accounts.transactions &&
  accounts.transactions.find(a => !a.isPending); //😬

The logical operator && is used to terminate the execute as soon a falsy value (0, undefined, null, "", NaN) is encountered. Meet the optional chaining operator ?.. Similarly, it short circuits the chain of property accesses and returns undefined when a left-hand operand is either null or undefined. Note empty strings and 0 are valid operands for this operator ⚠️. Okay, here is the same code above using optional chaining operator.

declare var accounts;
declare var axiosError;

const didError = axiosError?.response?.status === 404
const transaction =  accounts?.transactions?.find(a => !a.isPending); // Hello there gorgeous 😄.

All the conditional branches and verbosity are out of sight ! Handy isn’t it ?.

// Transpiled output.
// NOTE that it only checks whether or not the property value is null or undefined (void 0)
const account = {};

// account?.merchant
const merchant = account === null || account === void 0 ? void 0 : _a.merchant;

Now that we’ve seen how the operator works, let’s see the semantics.

Optional property access
This is the base usage. Allows property access if the operand on the left-side of the the operator is not null or undefined.

const transactionId = account?.transactions?.transactionsId;

Optional element access
This is similar to optional property access but for dynamic property access.

declare var todos;

const todo = todos?.[0];

Optional call
This is a variation of optional property access for nullable/undefined methods;

function getIterator (arg?: any[]) {
 return arg[Symbol.iterator]?.();
}

Short-circuiting
Because the chain is terminated when the expression on the left-hand side evaluates to null or undefined, we are able to do this. The right hand side expression is not evaluated.

declare var source;
declare var next: number;

source?.[next++]  // next is not incremented if source is `undefined` or `null`

Stacking
Finally, the semantics above can be utilised in a single property access chain. Below we see the use of optional property access, optional elements access and optional call in a single property accesses expression.

declare var tween;

tween?.config.colors?.[0].setHue?.(60).result

I urge you to try these out on the typescript playground and see the transpiled output of these examples for completeness ! 😀.

Nullish Coalescing

The nullish coalescing operator ?? is a complementary operator to the optional chaining operator. Similar to || logical operator, It provides a way to “fallback”. The difference here is that, it only falls back when the operand is either null or undefined, whereas || will do for falsy values (NaN, false, 0, '').

Before

const tween = {
  type: 'Mother ship',
  config: {
    colors: [],
    animation: { multiplier: null, delay: 0, startHidden: false },
  },
};

const multiplier = tween.config.animation.multiplier || 2; // multiplier falls back to 2
const timing = tween.config.animation.timing || 'linear'; // timing falls back to 'linear'
const delay = tween.config.animation.delay || 1000; // delay falls back to 1000 😬⚠️.
const hidden = tween.config.animation.startHidden || true; //  😬⚠️.

We risk valid/present property values falling back to something else. Nullish coalescing is especially useful where we expect common cases of null or undefined.

After

const tween = {

  type: 'Mother ship',
  config: {
    colors: [],
    animation: { multiplier: null, delay: 0, startHidden: false  },
  },
};

// Undefined/null
const multiplier = tween.config.animation.multiplier ?? 2; // multiplier:2
const timing = tween.config.animation.timing ?? 'linear'; // timing:'linear'

//falsy values
const delay = tween.config.animation.delay ??  1000; // delay:0 ✅.
const hidden = tween.config.animation.startHidden || true; //hidden: false ✅.

Use with optional chaining

declare var player
const playerScore = player?.score ?? 1; // playerScore is 1 if score has value  null or undefined. 0 is a valid score !.

There are other tasty treats in this release such as Assertion Functions, Better Support for never-Returning Functions, Recursive Type Aliases, Uncalled Function checks etc. See for what is new. Until next time stay curious.

Published on November 2019