Static type checking in Javascript using Flow

Aug 21, 2016

Javascript has a dynamic type system which removes a lot of the boilerplate from your code with the cost of type safety. In early 2000 dynamically typed languages such as Python and Ruby were on the rise to challenge Java’s verbosity with the simplicity of dynamic typing. Somewhere in the middle ground lay statically typed languages with type inference, such as Scala.

Static typing vs. dynamic typing

Depending on the context, there are cases where dynamically typed languages are better match and cases where statically typed languages are better suited. When you want to get something simple done quickly, then strong and static typing system might feel like overkill and something like NodeJS + Express might be the ideal fit.

When the application domain is large and complex, involving a lot of data manipulation, then statically typed languages might help you in taming the domain. But as always in matters related to programming and technical decisions, your mileage may vary.

Flow to the rescue

Back to Javascript however. In the autumn of 2014, Facebook developed a static type checker for Javascript called Flowtype. Flow is an additional type system syntax on top of vanilla JS and it is transpiled using a tool like Babel in the same way as ES6. I thought I’d give Flow a try with one of my hobby projects, finnish-business-ids. The repo is very simple, but it contains all the bits and pieces to get running with Flow.

Flow’s syntax builds on top of Javascript and features static typing for simple variables, arrays, classes, objects, functions and so forth. You can check the details from the documentation. I will focus here on demonstrating the impact on developer experience when using Flow with an editor like IDEA.

Type metadata in IDEA autocomplete

IDEA can be configured to use Flow as “Javascript language version”. After this, IDEA will offer you autocomplete for functions with type information as illustrated in the screenshot below. You can also declare your own types, which is extremely handy when using the òptions-pattern.

Enforce type annotation using ESLint

You can configure ESLint to enforce the level of additional type annotations you want to have for your project. In my example project, I have configured ESLint to enforce type annotation on function parameter types and return types. Now that my editor is aware of this, it will highlight the erroneous lines.

To play it really safe I have ESlint with Flow configured in my “pre-commit”-hook, which is configured in package.json. This gives me fast feedback from my editor and the safety before committing changes to Git.

A look under the hood

So what kind of magic does Flow do under the hood? In the transpiled code below we can see Flow adding a few lines for checking the parameters and the return value as seen in the screenshot below. This might bring a very small performance impact, but nothing to worry in this case.

Aftermath

I’m not 100% convinced that I would pull Flow for my next NodeJS project. I kind of like the simple approach and the possibility to decide the level of static typing I want using ESLint. However, if the domain I am working is complex, then perhaps a programming language with strong type system might be the weapon of choice. If I want something simple and straight forward with Javascript, then perhaps I can live without static typing.

Author info

Building solutions with my Wunderful fellow coders at Wunderdog ltd in Helsinki, Finland. Interested in clean code, frontend, backend, automation, devops, agile, lean and keeping the feedback loop short. Always focused on delivering business capabilities and most importantly, business impact. Professional since 2001.

Ville Komulainen

Building solutions with my Wunderful fellow coders at Wunderdog ltd in Helsinki, Finland. Interested in clean code, frontend, backend, automation, devops, agile, lean and keeping the feedback loop short. Always focused on delivering business capabilities and most importantly, business impact. Professional since 2001.