Flow
& bringing types to our JavaScript
William Beard
Engineer @ CA Agile Central
etc., etc., etc.
Some context
You're just not my type

Object is not an Immutable.Map
Immutable.Map is not an Object


Cross-app Actions
Runtime Errors

Goals
- Know when something is Immutable and when not.
- Know what a function expects & what it returns.
- Reduce runtime errors.
Types

What is flow?
A static type checker for JavaScript
- Built in JS types (number, string, boolean, etc).
- Custom JS types (immutable ships with flow type definitions & you can write your own).
- CLI & integration with Atom with nuclide.
- Incrementally introduce into codebase.
- Babel plugin for removing annotations & other cruft.
How it works
- 
	Creates a dependency graph of your modules. 
- 
	Runs the modules' interactions through a rules engine. 
- 
	Screams loudly if you break the rules. 
Why it works for us
- 
	No more spilled cheetos. 
- 
	Screams loudly when we pass the wrong thing to a function. 
- 
	Know the shape of the payload an action expects. 
- 
	No bugs ever again (LOL). But seriously, no more "cannot read property foo of null". 
How to use Flow
cd path/to/your/project
npm install --save-dev flow-bin babel-transform-flow-strip-types
touch .flowconfig
# add // @flow to a file, any file
./node_modules/.bin/flowAdding types to a file
// @flow
function doABarrelRoll(barrelName: string, timesToRoll: number): string {
  return `${barrelName} is doing a barrel role ${timesToRoll} times`;
}
doABarrelRoll({ name: 'Stan' }, 'hi');flow_test.js:6
  6: doABarrelRoll({ name: 'Stan' }, 'hi');
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
  6: doABarrelRoll({ name: 'Stan' }, 'hi');
                   ^^^^^^^^^^^^^^^^ object literal. This type is incompatible with
  2: function doABarrelRoll(barrelName: string, timesToRoll: number): string {
                                        ^^^^^^ string
flow_test.js:6
  6: doABarrelRoll({ name: 'Stan' }, 'hi');
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
  6: doABarrelRoll({ name: 'Stan' }, 'hi');
                                     ^^^^ string. This type is incompatible with
  2: function doABarrelRoll(barrelName: string, timesToRoll: number): string {
                                                             ^^^^^^ numberImmutable.js types
Get for free when you import immutable.
import { List, Map } from 'immutable';
export const listToArray = (list: List): array => list.toJS();
export const mapToObject = (map: Map): object => map.toJS();Action Creators
// @flow
import { Map } from 'immutable';
type UserStoryCreatedAction = {
  type: string,
  payload: Map
};
export function createdUserStory(userStory: Map): UserStoryCreatedAction {
  return {
    type: 'USER_STORY_CREATED',
    payload: userStory
  };
};
// @flow
import { createdUserStory } from './userActions';
var userStory = {
  title: 'Create a user story',
  estimate: 13
};
createdUserStory(userStory);
flow_test.js:9
  9: createdUserStory(userStory);
     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ function call
  9: createdUserStory(userStory);
                      ^^^^^^^^^ object literal. This type is incompatible with
  7: export function createdUserStory(userStory: Map): UserStoryCreatedAction {
                                                 ^^^ Map. See: userActions.js:7Null safety
// @flow
function doABarrelRoll(barrelName: string, timesToRoll: number): ?Object {
  return { name: barrelName, roll: timesToRoll };
}
function ultraBarrelRoll(): string {
  var barrelRoll = doABarrelRoll('Stan', 3);
  return `${barrelRoll.name} is now doing ${barrelRoll.roll} ultra barrel rolls`;
}
ultraBarrelRoll();
flow_test.js:9
  9: return `Ultra ${barrelRoll.name} is now doing ${barrelRoll.roll} barrel rolls`;
                                  ^^^^ property `name`. Property cannot be accessed
                                       on possibly null value
  9: return `Ultra ${barrelRoll.name} is now doing ${barrelRoll.roll} barrel rolls`;
                       ^^^^^^^^^^ null
flow_test.js:9
  9: return `Ultra ${barrelRoll.name} is now doing ${barrelRoll.roll} barrel rolls`;
                                                                ^^^^ property `roll`. 
                                    Property cannot be accessed on possibly null value
  9: return `Ultra ${barrelRoll.name} is now doing ${barrelRoll.roll} barrel rolls`;
                                                       ^^^^^^^^^^ nullCustom Types
- 
	<PROJECT_ROOT>/flow-typed 
- 
	[libs] in .flowconfig 
- 
	Declaration file next to implementation file (why Immtuable types are free) - 
		Project Root - 
			actions - 
				UserStoryActions.js 
- 
				UserStoryActions.js.flow 
 
- 
				
 
- 
			
 
- 
		
type UserStoryCreatedAction = {
  type: string,
  payload: Map
};.flowconfig
aka Ignore a lot of your node_modules

[version]
Specify a specific version of flow
[version]
0.27.0[include]
Run analysis on code external to your project
[ignore]
Don't analyze these files. Useful for excluding problems that live in dependencies.
[ignore]
# Malformed json in `test/pkg-bower-json-malformed/bower.json:2`
.*/node_modules/bower-json/.*
# Malformed json in `test/broken.json:11`
.*/node_modules/config-chain/.*
# Malformed json in `test/fixtures/node_modules/invalidPackageJson/package.json: 1`
.*/node_modules/enhanced-resolve/.*[libs]
Tell flow where your custom types live. As of flow 0.24.0, it will check for custom types in <PROJECT_ROOT>/flow-typed.
[options]
A lot you can do here. tldr; Enable certain es2015+ features.
[options]
# Ignore flow warnings about not supporting decorator types
esproposal.decorators=ignore
# Ignore flow warnings about not support static fields
esproposal.class_static_fields=ignore
# Ignore flow warnings about not supporting instance fields
esproposal.class_instance_fields=ignore
Nuclide

npm install -g flow-bin
apm install nuclideFlow errors in atom

Autocomplete w/ function signatures

Also Type hinting & jump to definition
npm task
// package.json
"scripts": {
  ...
  "flow": "./node_modules/.bin/flow"
  ...
}Results may vary
Speed has been inconsistent. Nuclide can be a pain.
Learn more
Thanks!
@thewillbeard
Flow all up in our javascripts
By willb
Flow all up in our javascripts
- 1,426
 
   
   
  