干掉错误

常见错误以及解决方法#

Global not found#

这类错误是由于代码中引用了全局变量,也可能是由于手贱敲错。 如果是前者,并且你知道运行时是没问题的, 你可以 通过定义接口文件 解决。

1
declare var foo: <type>;

Required module not found#

这类错误由于 require(...) 或者 import 使用的模块不是 <根目录> 下的,可以通过下面配置,让 Flow 包含额外的目录。

[include]
../node_modules/
../lib/

如果无没法访问到这些外部模块,又想要声明他们的类型。 这就像上面提到 ‘global not found’ 的情况,你需要创建接口文件,然后配置到 .flowconfig

1
2
3
declare module Bar {
  ...
}

更多关于创建接口文件的内容,请查看 这篇指南

注意,如果一个模块的实现(源码)和声明(接口文件)都能找到,如果实现上明确要检测(@flow), 那么就会使用实现的,否则使用声明的。

Operation not allowed on null / undefined#

Flow 通常认为具体类型和 null / undefined 是冲突的 (只有一种兼容的类型是兼容 null 类型的,即 ?<type>)。

所以说,如果发现一个操作可能发生在 null / undefined 上,Flow 就会报错, 大家都知道在 null 上操作是会报错的。

解决这类问题的一般思路是先用局部变量存储这个值,然后做个条件判断, 如果不是非法的,再进行操作。

1
2
3
// var result = foo().bar
var x = foo();
var result = x != null ? x.bar : ...

同样的思路,换个写法:

1
2
// foo.bar()
foo && foo.bar()

Function call with too few arguments#

在 Javascript 的世界里,方法调用传递的参数可多可少。 多了的参数就多了,少了的参数就会初始化为 undefined。 Flow 对前者无感,毕竟它无害;不过对后者就会报错。

The most common way to fix these errors is to mark optional parameters with a trailing-? in the definition for the function being called:

最常见的解决方法,就是在定义函数的参数后面加一个 ?,标记为可选参数

1
2
function foo(x?) { ... }
foo();

你这么做之后呢,方法的定义又会报错,因为 x 现在是可选类型, 所以对 x 操作之前都要作条件判断。

1
2
3
4
5
6
function foo(x?) {
  if (x != undefined) {
    // operation on x
  }
}
foo();

另外,你还可以简单的给 x 一个默认值,这样就不用作条件保护了

1
2
3
4
function foo(x = 0) {
  // operation on x
}
foo();

其他错误#

有些操作运算只对部分值有效。(虽然对别的值使用不会挂,但不是你想要的)

例如,乘操作 (*) 应该用在数字上,但有时候不小心用在字符串上了 (尽管不会挂掉,但是通常会被转化成 NaN

使用 for-in 遍历应该用在对象上,即便用在数组上也不会报错 (索引被转成字符串或者其它,通常都不是你想要的)

弱等于 == 应该用在两个类型相同的值上(可是,它会试着偷偷转换类型再比较)

Flow 会对包括以上的这类用法报错,因为它们是潜在的危险。 对于这些不良代码,通常都有一个安全的方式来改写,例如, 举例中的后两种,可以使用 Array.forEach=== 来解决, 而第一种可以用 Number(...)

← Prev Next →

You can edit this page on GitHub and send us a pull request!