FLOW IS A STATIC TYPE CHECKER FOR JAVASCRIPT.
node
安装完成后执行 flow init 会自动生成一个 .flowconfig 文件,这个文件告诉 Flow 须要检测根目录以及全部子目录的代码。(.flowconfig 有一些高级配置在下面的章节会讲到。)react
$> mkdir new_project
$> cd new_project
$> flow init
|
有了配置文件,咱们就能够使用下面的指令检测代码了:git
$> flow check
# 全量检查
$> flow
# 开启一个后台服务,输出首次检测结果,当发生修改时,再次运行 flow 会增量地检查文件
$> flow stop
# 代码写完,关闭服务
|
对于须要使用 flow 进行类型检查的 js 文件,在开头加入 @flow 注释。github
/* @flow */
/* @flow weak */
只对有加类型注解的变量进行类型检测
|
无论有没有 @flow 注释,均可以使用 flow check --all 强制检查全部文件。web
function concat(a, b) {
return a + b;
}
concat("A", "B"); // Works!
concat(1, 2); // Works!
// @flow
function concat(a: string, b: string) {
return a + b;
}
concat("A", "B"); // Works!
concat(1, 2); // Error!
|
null
undefined
(void
in Flow types)
// @flow
function getColor(name: "success" | "warning" | "danger") {
switch (name) {
case "success" : return "green";
case "warning" : return "yellow";
case "danger" : return "red";
}
}
getColor("success"); // Works!
getColor("danger"); // Works!
// $ExpectError
getColor("error"); // Error!
|
function stringifyBasicValue(value: string | number | boolean) {
return '' + value;
}
|
应该尽量避免,可是在作项目迁移时,能够使用 any 作平稳过渡。——能用 mixed 就不用 any。typescript
// @flow
function acceptsMaybeNumber(value: ?number) {
// ...
}
acceptsMaybeNumber(42); // Works!
acceptsMaybeNumber(); // Works!
acceptsMaybeNumber(undefined); // Works!
acceptsMaybeNumber(null); // Works!
acceptsMaybeNumber("42");
|
var
varVariable = 1;
let letVariable = 1;
const constVariable = 1;
varVariable = 2;
// Works!
letVariable = 2;
// Works!
// $ExpectError
constVariable = 2;
// Error!
|
主要概念:参数、函数返回值、可选参数、rest 参数。npm
let method = (str: string, bool?: boolean, ...nums: Array<number>): void => {
// ...
};
|
// @flow
var obj = { foo: "bar" };
// $ExpectError
obj.bar; // Error!(not undefined)
|
sealed object 不容许被添加新属性。redux
// @flow
var obj = {
foo: 1
};
// $ExpectError
obj.bar = true; // Error!
// $ExpectError
obj.baz = 'three'; // Error!
|
若是对象在建立时没有任何属性,那么它就是 unsealed object,容许添加属性。若是 flow 能推断出这个属性的类型,就给他指明类型,不然,给他全部可能的类型。vim
// @flow
var obj = {};
obj.foo = 1; // Works!
obj.bar = true; // Works!
obj.baz = 'three'; // Works!
// @flow
var obj = {};
obj.prop = true;
obj.prop = "hello";
// $ExpectError
var val1: boolean = obj.prop; // Error!
var val2: string = obj.prop; // Works!
// @flow
var obj = {};
if (Math.random()) obj.prop = true;
else obj.prop = "hello";
// $ExpectError
var val1: boolean = obj.prop; // Error!
// $ExpectError
var val2: string = obj.prop; // Error!
var val3: boolean | string = obj.prop; // Works!
|
let arr1: Array<boolean> = [true, false, true];
let arr2: Array<string> = ["A", "B", "C"];
let arr3: Array<mixed> = [1, true, "three"];
|
除了上面介绍的类型,还有不少其余的 types,能够直接去官网查看。sublime-text
$> npm clone https:
//github.com/facebook/flow.git
$> cd flow/examlpes
$> flow
|
相似npm
$> flow --help
$> flow cmd --help
|
[include]
../externalFile.js
../externalDir/
[ignore]
.*/build/.*
[libs]
./lib
[options]
module.system.node.resolve_dirname=node_modules
module.use_strict=true
[version]
0.22.0
|
通常来讲,咱们不想去检测第三方模块的代码,官方推荐的作法是使用 flow-typed。
若是在 flow-typed 中找不到定义好的模块,也能够本身本身写。
// Declaring A Global Function
declare function foo(a: number): string;
// Declaring A Global Class
declare class URL {
constructor(urlStr: string): URL;
toString(): string;
static compare(url1: URL, url2: URL): boolean;
};
// Declaring A Global Variable
declare var PI: number;
// Declaring A Global Type
declare type UserID = number;
// Declaring A Module
declare module "some-third-party-library" {
// This is where we'll list the module's exported interface(s)
}
// Declaring An ES Module
declare module "some-es-module" {
// Declares a named "concatPath" export
declare export function concatPath(dirA: string, dirB: string): string;
}
// Declaring A CommonJS Module
declare module "some-commonjs-module" {
// The export of this module is an object with a "concatPath" method
declare module.exports: {
concatPath(dirA: string, dirB: string): string;
};
}
|
$> npm install --save-dev babel-preset-flow
|
{
"presets": ["flow"]
}
|
|
flow
|
typescript
|
---|---|---|
slogan | A static type checker for JavaScript | JavaScript that scales |
开发者 | 微软 | |
相关技术 | React | Angular |
star | 1w+ | 2w+ |
文档 | 少 | 多 |
第三方库支持 | 弱 (flow-typed) | 强 (tsd) |
IDE支持 | 弱 | 强 |
其余 | 自由度高,老项目迁移比较方便 | 工程化强,适合新项目、大项目 |