Flow is a static type checker for JavaScript. With it, you can add types to any existing JS code.
Without flow:
function foo(x, y) {
return x.length * y;
}
With flow:
// @flow
function foo(x: string, y: number): number {
return x.length * y;
}
When passing in a Number
for the value of x
, Flow will spit out an error.
Even without annotations, Flow can notify you of wrong types. The snippet below for example – where one passes in a String
into the function, where it should obviously be a Number
– will also make flow spit out an error:
// @flow
function foo(x) {
return x * 10;
}
foo('Hello, world!');
How does Flow notice it?
Flow uses type inference to find bugs even without type annotations. It precisely tracks the types of variables as they flow through your program.
Flow checks all JavaScript files that contain the // @flow
comment. You can also use // @flow weak
to make Flow run in weak mode. This mode is handy when starting to use Flow in an existing project:
In regular mode Flow will infer types for all missing annotations, and produce errors whenever it detects a mismatch. In weak mode, Flow will do much less type inference. It will still infer types within functions, but will otherwise treat unannotated variables as having the any type – meaning no typechecking happens on them.
You can run Flow yourself, or you can integrate it into your existing build script. For use with Babel – since types are not part of the JavaScript specification – you need the transform-flow-strip-types
plugin to strip out the type annotations.
npm i babel-plugin-transform-flow-strip-types --save-dev
Don’t forget to update your .babelrc
file to include the transform-flow-strip-types
plugin.
{
"presets": ["es2015", "react", "stage-0"],
"plugins": ["transform-flow-strip-types"]
}
Using a .flowconfig
file (yes, that’s another dotfile in your project root :-P) you can configure Flow to include certain files/directories, ignore certain files/directories, make it play nice with external libraries (using interface files), and set it’s options. Having glanced at some projects that use Flow, I’ve found these options to be common:
[options]
esproposal.class_static_fields=enable
esproposal.class_instance_fields=enable