DEV Community

Cover image for Typescript: use the nullish coalescing operator to prevent bugs
Maxime Thoonsen 🌳
Maxime Thoonsen 🌳

Posted on • Originally published at blog.theodo.com

Typescript: use the nullish coalescing operator to prevent bugs

My goal as a CTO is to improve quality. The score of this game is the number of bugs we find each week. Today I share with you a typical bug that more than one person got caught by.

Let's say you want to initialize the audio volume of your react application with the value previously saved in the localStorage or defaulting it to 0.5 if nothing was saved. You could write something like:

Bad example

function initializeAudio() {
  let volume = localStorage.volume || 0.5;

  // ...
}

The problem is that if the user has saved their volume to 0 it will be interpreted as falsy and your code will use the default value instead of the right value. Some devs prefer the simplicity of || than putting an explicit if clause. And more than once, they were right because 0 was not a plausible value. But as a standard it is too dangerous. For example someone else could see the code and think the || is a good coding stantard in all situation which will eventually create a bug.

Typescript 3.7 comes with the best option: you can now use the nullish coalescing operator to prevent that wrong behavior and safely write something like:

Good example

function initializeAudio() {
  let volume = localStorage.volume ?? 0.5;

  // ...
}

That will be compiled in:

function initializeAudio() {
    var _a;
    var volume = (_a = localStorage.volume) !== null && _a !== void 0 ? _a : 0.5;
    // ...
}

To make sure people from your team use it, you can use the prefer-nullish-coalescing ESLint rule. You can also use it with javascript and this babel plugin. If you want to go deeper in the understanding of this operator you can go here.

I hope this article will help your team prevent this kind of bugs. For more actionable code quality tips, find me on Twitter.

And you? What's your secrets to prevent bugs in your application?

Top comments (4)

Collapse
 
functional_js profile image
Functional Javascript

Good tip Maxime.

If one is using pure JavaScript, one can do:

/**
@func
if the num is nil, then return a default num instead

@param {number} def - default num to return if n is nil
@param {number} n - expected to be a num; if not, then return the default num
@return {number} - the original n or default num
*/
const getNumOrDefault = (def, n) => isNil(n) ? def : n;
Enter fullscreen mode Exit fullscreen mode

usage:

//@tests
getNumOrDefault(0.5, localStorage.volume);
Enter fullscreen mode Exit fullscreen mode
Collapse
 
ivan_poiraudeau profile image
Ivan Poiraudeau

Thanks for the additional tip - is isNil coming from lodash?

Collapse
 
functional_js profile image
Functional Javascript

I have a post here on the isNil func:

dev.to/functional_js/null-vs-undef...

Collapse
 
ivan_poiraudeau profile image
Ivan Poiraudeau

You may also like the strict-boolean-expressions ESLint rule (with the allowNumber: false option)

Not only does it detects numbers in || expressions, but also in other boolean expressions such as !arg, cond ? x : y, etc.