Skip to content

Instantly share code, notes, and snippets.

@butaud
Last active October 11, 2022 19:13
Show Gist options
  • Save butaud/530199804885f2297522b486bda3ea11 to your computer and use it in GitHub Desktop.
Save butaud/530199804885f2297522b486bda3ea11 to your computer and use it in GitHub Desktop.
Against unncessary boolean casting

Against unnecessary boolean casting

tl;dr: Don't use !! in Javascript for conditions - instead, embrace "truthiness".

When is casting to boolean unnecessary?

Everyone knows that you can use !! to convert a value in Javascript to a Boolean based on the "truthiness" of the value. This is often necessary in Typescript when you need to set something typed as boolean based on whether some other value is defined. Here's a typical example:

typical boolean cast

But casting in this way is unnecessary when the purpose is to use the value in a conditional, like in this example:

unnecessary boolean cast

Conditionals operate just fine on the truthiness of the original value - there is no need to cast it.

Why does it matter?

You could argue that it's worth getting rid of these because of a general principle against unnecessary operations in the code, or for performance concerns. But I think those are both pretty minor in this case. Here's the reason why it's important to me to remove this cast: it's a crutch.

Most of us are uncomfortable with the "truthiness" feature when we start working in Javascript. Maybe we've heard of bugs cropping up because of it, or maybe sticking a non-boolean value directly into a conditional just makes us feel weird. Whatever the reason, casting to boolean seems like it gets us back to firmer ground - now we know that this thing we're testing is a boolean value and will just be plain true or false!

But in reality, casting to boolean doesn't change anything. Your conditional will still evaluate the same way in every case. Ultimately it's still testing the truthiness of the value, just with a theoretical extra step in the middle. So if you feel like it's protecting you from "truthiness" bugs, it may be giving you a false sense of security.

For better or for worse, truthiness is part of Javascript and Typescript and it is here to stay. If you try to insulate yourself from it so you don't need to worry about it, you may miss the occasions when it sneaks in anyway and bites you. Here's an example:

truthiness bug

Did you spot the bug? Typescript enums compile to plain Javascript numbers or strings, and by default they are just assigned integers starting at zero. A diner who prefers breakfast will be in for an unpleasant surprise when their choice is not respected since RestaurantType.BREAKFAST is a falsy value.

The unnecessary cast to boolean did not cause the bug here - the code behaves the exact same way without it. But it didn't protect you from the bug either. So leave it behind and develop the habit of thinking through whether a truthiness check will behave the way you want it to. (It's much easier in Typescript than in Javascript since you know what type you will get.) If it will do the right thing, great - no casting necessary! If not, then you will have to make the test more explicit - in the example above, by changing !!preference to preference !== undefined.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment