使用Flow写javascript

介绍

  • Flow是一个用于 JavaScript 的静态类型检查器,最早由 Facebook 在 2014 年的 Scale 大会 上推出。它的目标是不需要开发人员去频繁的修改实际代码,就能找到 JavaScript 代码中的类型错误,从而大大节省这方面时间与精力的消耗。同时,它也向 JavaScript 增加了额外的语法,以提供给开发者更多的控制能力。

安装

  • 使用 npm 安装

    1
    npm install --save-dev flow-bin
  • 添加到package.json 文件

    1
    2
    3
    "script":{
    "flow": "flow"
    }

入门

  • 先创建一个配置文件,放在根目录下

    1
    npm run flow init
  • 在终端执行如下命令检查

    1
    npm run flow check
  • 也可使用flow服务器检查

    1
    npm run flow
  • 停止用如下命令

    1
    npm run flow stop
  • 需要检查的文件只需在只在这些 JavaScript 文件顶部添加 @flow 作为注释就可以了

    1
    /*@flow/

类型推断

  • 有两种方法

    • 通过注解: 我们指定期望的类型并把它作为代码的一部分,类型检查器会基于这些期望来对代码进行评估。

    • 通过代码推断: 工具聪明到可以通过查看代码被使用的上下文来推断出类型,并基于此对代码进行检查。

  • 如下示例

    1
    2
    3
    4
    5
    6
    /*@flow*/
    function foo(x) {
    return x.split(' ');
    }
    foo(34);
    • 这段代码会在你运行 npm run flow 命令的时候在终端上报错, 因为函数 foo() 需要的是一个字符串作为参数,而我们传入的却是一个数字。

    • 报错提示大概如下:

      1
      2
      3
      4
      5
      index.js:4
      4: return x.split(' ');
      ^^^^^ property `split`. Property not found in
      4: return x.split(' ');
      ^ Number
    • 它明确说明了错误的位置和发生的原因。当我们将参数从数字修改为字符串,报错就会消失,如下:

1
2
3
4
5
6
7
/*@flow*/
function foo(x) {
return x.split(' ');
};
foo('Hello World!');
  • 上面的代码就不会报错。在这里我们能发现的就是 Flow 理解了 split() 方法只适用于字符串,所以适合的 x 就必须是一个字符串。

可为空类型

  • Flow 不像其它的类型系统一样对待 null。它不会忽略掉null,因此它可以防范那些作为其他类型传入的null可能会导致应用程序崩溃的问题。
1
2
3
4
5
6
7
/*@flow*/
function stringLength (str) {
return str.length;
}
var length = stringLength(null);
  • 在上述场景中,Flow 会抛出一个错误, 我们就不得不像下面这样对 null 进行单独的处理:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*@flow*/
    function stringLength (str) {
    if (str !== null) {
    return str.length;
    }
    return 0;
    }
    var length = stringLength(null);
  • 为了保证代码在所有的情况下都能正常运行,我们专门针对 null 进行检查。Flow 就会将最后的那行代码当做是有效的代码。

函数

1
2
3
4
5
6
7
8
/*@flow*/
/*--------- Type annotating a function --------*/
function add(x : number, y : number) : number {
return x + y;
}
add(3, 4);
  • 上面的代码展示了一个变量和一个函数的注解。add()函数的参数以及返回值都被期望是数字的。如果传入了任何其它的数据类型, Flow 就会抛出一个错误。

数组

1
2
/*-------- Type annotating an array ----------*/
var foo : Array<number> = [1,2,3];
  • 数组注解采用 Array 的形式,其中的 T 表示数组中单个元素的数据类型。在上述代码中,foo应该是一个元素为数字的数组。

  • 如下是类和对象的一个示例模式。唯一需要牢记的一点是我们可以使用 | 符号在两个类型间执行 OR 操作。变量 bar1 被加上了注解,期望的是 Bar 类的模式。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    /*-------- Type annotating a Class ---------*/
    class Bar{
    x:string; // x should be string
    y:string | number; // y can be either a string or a number
    constructor(x,y){
    this.x=x;
    this.y=y;
    }
    }
    var bar1 : Bar = new Bar("hello",4);

文章来自flow