Redux and Flowtype

A practical introductory walkthrough for static typing

First, I want to begin by stating that this is not an article about how to use Redux, there’s a ton of fantastic documentation out there already, I want to discuss how you apply the concepts of static typing to Redux. Flow is a static type checker for JavaScript, created by the engineering team at Facebook. Static typing adds a lot of value to your code, but it’s a strange topic for people who don’t come from programming in statically typed languages like C or Java. Let’s jump in by writing some non-typed redux code. We’re going to build a set of controls for an audio player. I’m assuming you’re familiar with all of this so I won’t do much explaining.


First, let’s define our constants.

constants/actionTypes.js

This is going to be a crazy easy file to statically type as we’re just declaring a bunch of string constants. Flow also infers the types of a variable based on the value that it’s instantiated with, so we technically don’t need to do anything here other than add the appropriate banner to our file that instructs flow to parse it. If we want to we can declare the types explicitly, which I’ll do here just to set us up for more complicated declarations.

constants/actionTypes.js

Flow allows you declare types as several primitives: string, number, boolean, Function, Array, Object, any, mixed, and void. If you’re instantiating without a value, or a variable can potentially be `null`, you precede your type declaration with a ?, eg: ?string?number?boolean.


Now that that’s out of the way, let’s look at something slightly more intricate, and dive into actions.

actions/playerActions.js

We’re dealing with functions now, so need to dictate the types of variables that pass into functions as well as the return values. For this example, we’re going to define a custom action type that is returned from each method, like a boolean, string, or number declaration, but a more fine-tuned declaration of an object type with it’s properties. Here’ what our action type is going to look like:

You’ll notice we’re exporting our types, like any other JavaScript module, this will allow us to import and export types from our JavaScript modules, so the data can be shared. The track type is going to reference another type declaration, that describes what an audio track is. This will look like:

Ultimately, the track type will not live in our actions/playerActions.js file, it should live with our reducer as that in a way describes our client model data. Let’s assume this is going in reducers/player, and import it from there.

actions/playerActions.js

Slightly more complicated than our super-simple constant declarations, we’re just labeling all variables and return values with types. In this case, most of our types are custom definitions. Each action returns a PlayerAction type, which defines all possible types that can be sent to our reducers. We’re also importing our track from our reducer file, which almost acts like a type definition for model data.


So now that that’s all out of the way, let’s take a look at our reducer, which is easily the most interesting module. Hopefully you’re a little more comfortable with how typings are declared because we’re going to skip the non-statically typed version.

reducers/player.js

And that’s it. We have our statically typed redux tools. If any part of our application tries to pass data into our state that doesn’t strictly conform to our declared typings, we will get an error before we ever go into a browser, which is invaluable in saving debugging time. As an added bonus, if you use nuclide as your IDE, you will get type hinting throughout your code. This type hinting will make it extraordinarily easy for other developers to start working in your code.