Flow v0.19.0 was deployed today! It has a ton of changes, which the Changelog summarizes. The Changelog can be a little concise, though, so here are some longer explanations for some of the changes. Hope this helps!

@noflow

Flow is opt-in by default (you add @flow to a file). However we noticed that sometimes people would add Flow annotations to files that were missing @flow . Often, these people didn’t notice that the file was being ignored by Flow. So we decided to stop allowing Flow syntax in non-Flow files. This is easily fixed by adding either @flow or @noflow to your file. The former will make the file a Flow file. The latter will tell Flow to completely ignore the file.

Declaration files

Files that end with .flow are now treated specially. They are the preferred provider of modules. That is if both foo.js and foo.js.flow exist, then when you write import Foo from './foo' , Flow will use the type exported from foo.js.flow rather than foo.js .

We imagine two main ways people will use .flow files.

As interface files. Maybe you have some library coolLibrary.js that is really hard to type with inline Flow types. You could put coolLibrary.js.flow next to it and declare the types that coolLibrary.js exports.

1 2 3 4 declare export var coolVar : number ; declare export function coolFunction ( ) : void ; declare export class coolClass { } {"value":"// coolLibrary.js.flow

declare export var coolVar: number;

declare export function coolFunction(): void;

declare export class coolClass {}

","tokens":[{"type":"Line","context":"comment","value":"// coolLibrary.js.flow","line":1,"start":0,"end":22},{"type":"T_DECLARE","context":"normal","value":"declare","line":2,"start":23,"end":30},{"type":"T_EXPORT","context":"normal","value":"export","line":2,"start":31,"end":37},{"type":"T_VAR","context":"normal","value":"var","line":2,"start":38,"end":41},{"type":"T_IDENTIFIER","context":"normal","value":"coolVar","line":2,"start":42,"end":49},{"type":"T_COLON","context":"type","value":":","line":2,"start":49,"end":50},{"type":"T_NUMBER_TYPE","context":"type","value":"number","line":2,"start":51,"end":57},{"type":"T_SEMICOLON","context":"normal","value":";","line":2,"start":57,"end":58},{"type":"T_DECLARE","context":"normal","value":"declare","line":3,"start":59,"end":66},{"type":"T_EXPORT","context":"normal","value":"export","line":3,"start":67,"end":73},{"type":"T_FUNCTION","context":"normal","value":"function","line":3,"start":74,"end":82},{"type":"T_IDENTIFIER","context":"normal","value":"coolFunction","line":3,"start":83,"end":95},{"type":"T_LPAREN","context":"type","value":"(","line":3,"start":95,"end":96},{"type":"T_RPAREN","context":"type","value":")","line":3,"start":96,"end":97},{"type":"T_COLON","context":"normal","value":":","line":3,"start":97,"end":98},{"type":"T_VOID_TYPE","context":"type","value":"void","line":3,"start":99,"end":103},{"type":"T_SEMICOLON","context":"normal","value":";","line":3,"start":103,"end":104},{"type":"T_DECLARE","context":"normal","value":"declare","line":4,"start":105,"end":112},{"type":"T_EXPORT","context":"normal","value":"export","line":4,"start":113,"end":119},{"type":"T_CLASS","context":"normal","value":"class","line":4,"start":120,"end":125},{"type":"T_IDENTIFIER","context":"normal","value":"coolClass","line":4,"start":126,"end":135},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":136,"end":137},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":137,"end":138}],"errors":[]}

As the original source. Maybe you want to ship the minified, transformed version of awesomeLibrary.js , but people who use awesomeLibrary.js also use Flow. Well you could do something like

cp awesomeLibraryOriginalCode.js awesomeLibrary.js.flow babel awesomeLibraryOriginalCode --out-file awesomeLibrary.js

Order of precedence for lib files

Now your local lib files will override the builtin lib files. Is one of the builtin flow libs wrong? Send a pull request! But then while you’re waiting for the next release, you can use your own definition! The order of precedence is as follows:

Any paths supplied on the command line via –lib The files found in the paths specified in the .flowconfig [libs] (in listing order) The Flow core library files

For example, if I want to override the builtin definition of Array and instead use my own version, I could update my .flowconfig to contain

// .flowconfig [libs] myArray.js

1 2 3 4 declare class Array < T > { } {"value":"// myArray.js

declare class Array<T> {

// Put whatever you like in here!

}

","tokens":[{"type":"Line","context":"comment","value":"// myArray.js","line":1,"start":0,"end":13},{"type":"T_DECLARE","context":"normal","value":"declare","line":2,"start":14,"end":21},{"type":"T_CLASS","context":"normal","value":"class","line":2,"start":22,"end":27},{"type":"T_IDENTIFIER","context":"normal","value":"Array","line":2,"start":28,"end":33},{"type":"T_LESS_THAN","context":"type","value":"<","line":2,"start":33,"end":34},{"type":"T_IDENTIFIER","context":"type","value":"T","line":2,"start":34,"end":35},{"type":"T_GREATER_THAN","context":"type","value":">","line":2,"start":35,"end":36},{"type":"T_LCURLY","context":"type","value":"{","line":2,"start":37,"end":38},{"type":"Line","context":"comment","value":"// Put whatever you like in here!","line":3,"start":41,"end":74},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":75,"end":76}],"errors":[]}

Deferred initialization

Previously the following code was an error, because the initialization of myString happens later. Now Flow is fine with it.