- Adding flow to a file
- Running flow
- Missing Annotation
- Where are types defined?
- Checking flow coverage
- Flow Conventions
- Common Errors
The debugger uses Facebook's flow type checker.
Rationale:
- code clarity - helps team members understand the code
- refactoring - guarantees functions integrate well
- code reviews - adds a static check like linting
yarn run flow
Go checkout the Flow related issues
Add // @flow
to the top of the file.
diff --git a/src/components/Editor.js b/src/components/Editor.js
index b0fe9a6..8889a56 100644
--- a/src/components/Editor.js
+++ b/src/components/Editor.js
@@ -1,3 +1,5 @@
+// @flow
+
Then run yarn run flow
in your terminal. The first run will likely take 30 seconds to initialize, but subsequent runs will be fast.
Here's a gif of flow being added to the SearchBar and a couple of issues being resolved.
flow coverage --color <path to file>
yarn run flow-coverage
yarn run flow-redux
yarn run flow-react
yarn run flow-utils
We are currently using the following conventions
- the type names should be CamelCased (e.g.
SourceText
) - the types used to annotate functions or methods defined in a module should be exported only when
they are supposed to be used by other modules (
export type ExtensionManifest = ...
) - any type imported from the other modules should be in the module preamble (near to the regular ES6 imports)
- all the flow type definitions should be as close as possible to the function they annotate
Problem: In this case, flow is not sure that the editor property is defined.
src/components/Editor/SearchBar.js:172
172: const ctx = { ed, cm: ed.codeMirror };
^^^^^^^^^^ property `codeMirror`. Property cannot be accessed on possibly undefined value
172: const ctx = { ed, cm: ed.codeMirror };
^^ undefined
Solution: make sure that the property is required.
--- a/src/components/Editor/SearchBar.js
+++ b/src/components/Editor/SearchBar.js
@@ -22,7 +22,7 @@ function countMatches(query, text) {
const SearchBar = React.createClass({
propTypes: {
+ editor: PropTypes.object.isRequired,
- editor: PropTypes.object,
sourceText: ImPropTypes.map.isRequired,
selectedSource: ImPropTypes.map
},
@@ -144,7 +144,8 @@ const SearchBar = Rea
This is a pretty common flow error and it is usually the simplest to fix.
It means that the new code added in the sources doesn't define the types of the functions and methods parameters, e.g. on the following snippet:
export default async function getValidatedManifest(sourceDir) {
...
}
flow is going to raise the error:
src/util/manifest.js:32
32: sourceDir
^^^^^^^^^ parameter `sourceDir`. Missing annotation
which is fixed by annotating the function correctly, e.g.:
export default async function getValidatedManifest(
sourceDir: string
): Promise<ExtensionManifest> {
...
}
Some of the flow errors are going to contain references to the two sides of the flowtype errors:
tests/unit/test-cmd/test.build.js:193
193: manifestData: basicManifest,
^^^^^^^^^^^^^ property `applications`. Property not found in
24: export type ExtensionManifest = {|
^ object type. See: src/util/manifest.js:24
- The first part points to the offending code (where the type violation has been found)
- The second part points to the violated type annotation (where the type has been defined)
When flow raises this kind of error (e.g. it is pretty common during a refactoring), we have to evaluate which one of the two sides is wrong.
As an example, by reading the above error it is not immediately clear which part should be fixed.
To be sure about which is the proper fix, we have to look at the code near to both the lines and evaluate the actual reason, e.g.:
- it is possible that we wrote some of the property names wrong (in the code or in the type definitions)
- or the defined type is supposed to contain a new property and it is not yet in the related type definitions