Static Type Checking in JavaScript Without Compiling
I mentioned in our last post that we are using Flow for static type checking to avoid common errors. In our React apps, we use a Babel plugin to strip the type annotations and make browser-compatible bundles. There are other times, such as Node.js services or Google Cloud Functions, where we want to write and run plain JavaScript that does not need to be compiled. Flow’s comment-based syntax allows us to have static type checking without compiling 🎉
Let’s take a look at an example shopping cart that calculates the total of items after a discount has been applied.
Everything works as expected. Over time, the store and its codebase grow. Now, the store supports selling items
in different currencies so the price
changes from a number to an object with currency
and amount
properties.
Do you see the error?
cur.price
on line 12 is now an object so total
becomes a string and the result of calculateDiscount
becomes NaN
😿
Flow’s comment-based syntax
This error could have been spotted earlier if we added type annotations. The comment-based syntax would look like this for the calculateDiscount
function:
// 10% off, maximum $25 discount
function calculateDiscount(total /*: number */) /*: number */ {
const MAX_TOTAL = 250
return (total >= MAX_TOTAL ? MAX_TOTAL : total) * 0.1
}
Notice the total
argument now has a comment /*: number */
indicating that it should be a number and that the function should return a number. Here’s the first version with complete type annotations and no errors.
When the second version of items
is used (with its currency
and amount
properties), Flow quickly identifies the issue as seen here. It’s then easy to change cur.price
to cur.price.amount
. Now, our third version has Flow types and is still plain JavaScript so it can be embedded and run directly in a Medium post 😸
We’ve been really happy with how easy it to adopt Flow over time as we need it, wherever we need it. If you’ve been avoiding type checking because of the compiling overhead, give Flow a try!