Type checking React with Flow v0.11
This is an old post - for an up-to-date guide see Flow Cookbook: Flow & React.
Flow v0.11 was released recently. The latest set of changes really improve type checking in React apps. But there are some guidelines to follow to get the full benefits.
Use ES6 classes
React added support in version 0.13 for implementing components as native Javascript classes (more information on that here). The latest version of the React type definitions take full advantage of class-based type checking features.
React.Component
takes type parameters
When creating a component, be sure to provide type parameters in your class declaration to describe the types of your props, default props, and state. Here is a modified example from the React blog:
Counter.propTypes =
Counter.defaultProps =
The parameter signature is React.Component<DefaultProps,Props,State>
.
This is not exactly documented;
but you can see types of React features in
Flow’s type declarations for React.
All of the type declarations in that folder are automatically loaded whenever Flow runs,
unless you use the --no-flowlib
option.
If you define a constructor for your component,
it is a good idea to annotate the props
argument too.
Unfortunately Flow does not make the connection that the constructor argument
has the same type as this.props
.
Note that I included type annotations on render()
and context
.
This is just because Flow generally requires type annotations for class method
arguments and return values.
When those type parameters are given, here are some of the things that Flow can check:
- when instantiating your component, the required props are given with correctly typed values.
- props that are not required have default values (checked only if
defaultProps
is defined) - references to
this.props
orthis.state
are checked to make sure that the properties accessed exist, and have a compatible type - properties set with
this.setState()
are declared in your state type and have the correct types
Use JSX
I mentioned above that Flow will check that components are given required props.
In my testing, there were some cases where this worked when I used JSX syntax,
but did not work with the plain Javascript React.createElement
option.
(The case I had trouble with was with a conditionally-rendered child in
a render
method -
my uses of of React.createElement
worked fine with both syntaxes.)
I suspect that engineers at Facebook tend to prefer JSX,
and, and maybe test code written with JSX syntax more heavily.
General-purpose features
What is nice is that most of the features that Flow uses to support React are general-purpose. As far as I can tell, the only feature in Flow that is React-specific is support for JSX syntax. But some of the features that make Flow work so well are not yet documented. For details, see my post on Advanced features in Flow