Skip to content
Adds static typing to JavaScript to improve developer productivity and code quality.
OCaml JavaScript Shell C CSS HTML Other
Branch: master
Clone or download
mvitousek and facebook-github-bot [optional-chaining] Optional chains used for typeof, instanceof, and …
…Array.isArray refinements

Similar to D18458524, which added support for refinements in literal comparisons with optional chains, this diff adds support for type comparisons with optional chains. For the most part this is a simple extension of the existing work in D18458524, in order to generate refinements for cases like this:
class C { ... }
declare var x: ?{
  arr: Array<number>,
  obj: {...},
  c: C,
  maybe_void: number | void
if (Array.isArray(x?.arr)) { ... }
if (typeof x?.obj === "object") { ... }
if (x?.c instanceof C) { ... }

In all of these conditionals, we can be certain that if the condition returns true, then `x` is not null or undefined, because short-circuiting always produces `undefined`, and
1. `Array.isArray(undefined) === false`
2. `typeof undefined === "undefined"`
3. For all X, `undefined instanceof X === false`.

Case 2 above means that we need to flip the predicates generated from the optional chain when looking at a program like:
if (typeof obj?.maybe_void === "undefined") { ... }
In that case, we don't know whether the conditional succeeding means that `obj` is null or undefined or if `obj.maybe_void` is void--it could be either. But in the else case of the if, we know that `obj` is not null or undefined and that `obj.maybe_void` is a number.

Reviewed By: panagosg7

Differential Revision: D18496275

fbshipit-source-id: 8eb2a23fe57838ee670e2894234e75ee0dbc8cf2
Latest commit 3c55d64 Nov 21, 2019
Type Name Latest commit message Commit time
Failed to load latest commit information.
.circleci [PR] [circle] upgrade to Circle 2.1 Aug 14, 2019
.github [PR] docs: label user reported bugs with "needs triage" label Mar 19, 2019
examples remove flux-chat example Feb 7, 2018
hack [hack] add is_empty method to hashSet Nov 20, 2019
js Make $Flow$DebugSleep cancelable Jul 20, 2018
lib [PR] fix libdef for navigator.mediaDevices.getUserMedia Nov 20, 2019
newtests [PR] module.system.node.main_field Nov 19, 2019
packages v0.112.0 Nov 12, 2019
prelude Better handling of Object.defineProperty and friends Sep 24, 2019
resources [PR] Fix appveyor opam2 build Jun 12, 2019
scripts Upgrade ocamlformat to v0.12.0 Nov 14, 2019
src [optional-chaining] Optional chains used for typeof, instanceof, and … Nov 21, 2019
tests [optional-chaining] Optional chains used for typeof, instanceof, and … Nov 21, 2019
website [PR] module.system.node.main_field Nov 19, 2019
.gitattributes [PR] Mark "tests/malformed_code/text.js" as binary Apr 27, 2017
.gitignore [PR] Dune support Jul 16, 2019
.merlin consolidate .merlin files Jun 28, 2019
.ocamlformat Upgrade ocamlformat to v0.12.0 Nov 14, 2019 Adopt Contributor Covenant Aug 30, 2019 Update Jan 29, 2019 v0.112.0 Nov 12, 2019
LICENSE Update LICENSE from BSD3 to MIT Sep 26, 2017
Makefile create refactoring service Nov 12, 2019 [PR] [DOCS] Updated readme urls to use https instead of http Oct 28, 2019
_tags Add ppx_deriving_show to polarity module Nov 20, 2019
appveyor.yml [PR] Bump required ocaml version to 4.07.1 Jul 26, 2019
dune [PR] Dune support Jul 16, 2019
dune-project [PR] Dune support Jul 16, 2019
dune-workspace [PR] Dune support Jul 16, 2019
opam v0.112.0 Nov 12, 2019
package.json bump sshpk dependency Jul 19, 2019 Utility to query multiple locs in file in Nov 11, 2019
tool Move tool into packages/ folder Jan 31, 2018
yarn.lock [lsp] fix test URIs on windows Oct 18, 2019

Flow Build Status Windows Build Status Join the chat at

Flow is a static typechecker for JavaScript. To find out more about Flow, check out

For a background on the project, please read this overview.



Flow works with:

  • macOS
  • Linux (64-bit)
  • Windows (64-bit, Windows 10 recommended)

There are binary distributions for each of these platforms and you can also build it from source on any of them as well.

Using Flow

Check out the installation instructions, and then how to get started.

Using Flow's parser from JavaScript

While Flow is written in OCaml, its parser is available as a compiled-to-JavaScript module published to npm, named flow-parser. Most end users of Flow will not need to use this parser directly, but JavaScript packages which make use of parsing Flow-typed JavaScript can use this to generate Flow's syntax tree with annotated types attached.

Building Flow from source

Flow is written in OCaml (OCaml 4.07.1 is required).

  1. Install opam:
  1. Initialize opam:
opam init
  1. Install OCaml and Flow's dependencies:
# from within this git checkout
opam switch create . --deps-only -y
  1. Build the flow binary:
eval $(opam env)

This produces the bin/flow binary.

  1. Build flow.js (optional):
opam install -y js_of_ocaml.3.4.0
make js

This produces bin/flow.js.

The Flow parser can also be compiled to JavaScript. Read how here.

Running the tests

To run the tests, first compile flow using make. Then run bash ./ bin/flow

There is a make test target that compiles and runs tests.

To run a subset of the tests you can pass a second argument to the file.

For example: bash bin/flow class | grep -v 'SKIP'

Join the Flow community


Flow is MIT-licensed (LICENSE). The website and documentation are licensed under the Creative Commons Attribution 4.0 license (website/LICENSE-DOCUMENTATION).

You can’t perform that action at this time.