Flow.js

 · 5 mins read

What is Flow?

Flow is a static type checker for your JavaScript code. It does a lot of work to make you more productive. Making you code faster, smarter, more confidently, and to a bigger scale.

Features

I personally appreciate these features most:

TYPE INFERENCE: Using data flow analysis, Flow infers types and tracks data as it moves through your code. You don’t need to fully annotate your code before Flow can start to find bugs.

REALTIME FEEDBACK: Flow gives you fast feedback while you code by incrementally rechecking your code as you make changes.

EASY INTEGRATION: Flow integrates well with many tools, making it easy to insert into your existing workflow and toolchain.

Flow is developed by Facebook, so it’s the prime type checking tool recommended for React. Besides, I noticed that Vue.js used Flow as well, I found the answer on Zhihu.

Here is a question about why Vue use Flow instead of Typescript, on quora-like website Zhihu,

Vue 2.0 为什么选用 Flow 进行静态代码检查而不是直接使用 TypeScript?.

This question is answered by Evan You, who is the father of Vue.js framework, however this is written in chinese…

Another passage about

Strict Types: Typescript, Flow, Javascript — to be or not to be?, is very helpful for learners.

I extract part of pros and cons of static type validating, for reference only.

Pros:

  • It Communicates the Purpose of the Function
  • It Scales Down Complex Error Handling
  • It Distinguishes Between Data and Behavior
  • Wipes Out Runtime Type Errors

Cons:

  • It May Confuse the Budding Developers
  • Demands Lots of Time and Practice
  • It Gives Developers a Deceitful Sense of Security

When to use

Use then:

  • Your project is big and complex
  • A huge team is responsible to handle the task
  • You may require to refactor the program in the long run
  • When your Team is Familiar with Statically Typed Language
  • When a Library Suggests TypeScript

Avoid using when:

  • You’re working alone on the project
  • Your requirements are limited or the task is simple in nature
  • You want to sidestep possible performance penalties
  • You want to sidestep annoying edge cases
  • You want to avoid extra costs

How it works

Flow checks your code for errors through static type annotations. These types allow you to tell Flow how you want your code to work, and Flow will make sure it does work that way.

Look at the straight example first.

<br />// @flow
function square(n: number): number {
  return n * n;
}

square("2"); // Error!

It’s easy right? Let’s go further.

JavaScript the good thing:

Developers like coding in JavaScript because it helps them move fast. The language facilitates fast prototyping of ideas via dynamic typing. The runtime provides the means for fast iteration on those ideas via dynamic compilation. This fuels a fast edit-refresh cycle, which promises an immersive coding experience that is quite appealing to creative developers.

The bad thing:

However, evolving and growing a JavaScript codebase is notoriously challenging. Developers cannot move fast when they break stuff. They hit frequent interruptions, spending a lot of time debugging silly mistakes, unraveling assumptions and guarantees made by libraries written by others, etc.

Goals of flow:

The overall mission of Flow is to deliver an immersive coding experience for JavaScript developers—a fast edit-refresh cycle—even as the codebase evolves and grows. In engineering terms, we identify two concrete goals that are important to this mission: precision and speed. These goals pervasively drive the design and implementation.

Perception

JavaScript bugs can have significant impact at Facebook. Developers want to find and fix as many bugs as they can by the time their code rolls out into production. So we must care about soundness. At the same time, we must also care about not reporting too many spurious errors, because a low signal/noise ratio implies a low fix rate.

In other words, we want Flow’s analysis to be precise in practice—it must model essential characteristics of the language accurately enough to understand the difference between idiomatic code and unintentional mistakes.

Precision also has other desirable consequences. When types are trustworthy, developers tend to rely on them to structure their code and reason about it, leading to cleaner and more efficient code with fewer dynamic checks. When type errors are trustworthy, developers can focus on what their code does rather than thinking about how to rewrite their code to satisfy (or work around) the type system.

Finally, precision enables useful developer tools to be built. In particular, the quality of results reported by Flow when the developer asks for the type of an expression, the definition reaching a reference, or the set of possible completions at a point through an IDE is correlated with the precision of Flow’s analysis.

Speed

Precision usually comes at the cost of speed. But while a precise analysis is desirable, most of the appeal of JavaScript is lost if we slow down the edit-refresh cycle by making developers wait as we compile.

In other words, we must engineer Flow’s analysis to be extremely fast—it must respond to code changes without noticeable delay, while still being precise enough in practice.

Like precision, speed also has other significant effects. When bugs are reported as the developer makes changes to code, they become part of the editing process—the developer doesn’t need to run the code to detect bugs, and tracing bugs back to the code becomes simpler. Similarly, when the IDE can show the type of an expression, the definition reaching a reference, etc. as the developer is coding, we have observed that productivity can improve dramatically.


Here I don’t want to dive deep into flow types and configuration, they are all on official tutorial.

Officical Portal