In this tutorial, you will learn a technique that if used correctly, can help you write code that contains fewer bugs. When writing any software, writing testable code is key. Unit tests should guarantee that the code you have written does what you expect it to do. There are many different types of ways of testing your code and in this tutorial, you will learn why using guards within your code are important. You will learn how you can write your own guards in a clean approach. Sound good?
What Is A Guard?
A guard is a check that guarantees that all your function parameters meet your minimum requirements. Using guards means that you can guarantee that your functions are called correctly.
When you add guards to your functions, you are declaring a set of assertions that must always hold true for that function to execute. No parameters can ever make the system behave in an unexpected way, if it does, an exception will be thrown. An example of a guard check could be that a parameter should never be falsey, or that a parameter has to meet certain criteria. If this is not the case, an exception is raised.
If you do this for every function you write, you will massively reduce the chance that your application can get into an unexpected state. Most bugs occur due to an application running in an unexpected way. The theory goes that by adding guards, you will avoid a certain type of bug appearing in your system!
Introducing Invariant
If you're sold on the importance of guaranteeing that your functions can only be called with valid arguments, then the next question is how to start implementing it? Your first instinct might be to start writing lots of your own guards, maybe something like this:
There are a few issues with this approach. One, this breaks the DRY principle. You'll end up copying this code throughout your codebase. If you want to change, say where the guard errors are logged, you will have to go through the entirety of your whole codebase and update all your custom guards. This is a bad architectural decision.
Your next instinct, might be to write a custom shared utility function to do this for you, however, why reinvent the wheel when you don't need to? Instead, I recommend using a package called invariant
. More information about invariant
can be found here. You can install invariant
using this NPM command:
After invariant
is installed, you can use it to protect and assert that the passed in parameters to your function meet your expectations, like so:
The cool things about invariant
are that when running your app and process.env.NODE_ENV
is not production, the guard will be mandatory. If process.env.NODE_ENV
is set to production, the message is optional – so they can be hidden. This way you can write tests for your code, test it thoroughly in development and when you push it to production your application will not break. It's the best of both worlds, checks that not hinder performance!
I've used Guards in my code for years to check props get set correctly. During this time guards have helped me catch hundreds of bugs. I'm hoping by now I've convinced you to start using them. Happy Coding 🤘