类型注解
JavaScript 是一门动态类型语言,语法上也没规定要明确表示类型。 下面是正常的 JavaScript 代码
1 2 3 4 5 | function add(num1, num2) { return num1 + num2; } var x = add(3, '0'); console.log(x); |
x
的值是什么? 3
还是 "30"
?还是 undefined
呢?
答案是 "30"
。
很多时候,这可能不是你想要的。
Flow 通过静态分析和类型注解,让你减少这类隐晦的 bug,让代码更加符合预期。
类型注解#
类型注解通常都以 :
开头,可以用在方法参数和返回值,还有变量声明,例如:
1 2 3 4 5 6 | function foo(a: string, b: number): void { ... } var x: boolean = someBool; class Bar { y: string; someMethod(a: number): string { ... } } |
简单例子#
可以简单地添加 @flow
作为注释,让 Flow 检测它
1 2 3 4 5 6 | /* @flow */ function add(num1, num2) { return num1 + num2; } var x = add(3, '0'); console.log(x); |
不过,Flow 没能发现任何错误。这是因为 +
运算符能够支持 number
和 string
类型的值,我们也没有明确指名参数类型必须为 number
1 2 3 4 5 6 | /* @flow */ function add(num1: number, num2: number): number { return num1 + num2; } var x: number = add(3, '0'); console.log(x); |
对上面代码执行类型检测,于是给出类型错误了,因为我们明确声明了参数和变量的类型
file.js:5
5: var x: number = add(3, '0');
^^^^^^^^^^^ function call
5: var x: number = add(3, '0');
^^^ string. This type is incompatible with
2: function add(num1: number, num2: number): number {
^^^^^^ number
Found 1 error
类型注解是必须的吗#
用上 Flow 并不意味一定要类型注解,唯一必须的就是上面提到的 @flow
注解.
就像上面的例子,这行注释让 Flow 知道要检测代码
1 2 3 4 5 6 | /* @flow */ function multPI(num1, num2) { return Math.PI * num1 * num2; } var x = multPI(3, '0'); console.log(x); |
因为 *
操作符不支持字符串运算,Flow 很聪明,无需类型注解就能够推断出问题
file.js:5
5: var x = multPI(3, '0');
^^^^^^^^^^^^^^ function call
3: return Math.PI * num1 * num2;
^^^^ string. This type is incompatible with
3: return Math.PI * num1 * num2;
^^^^^^^^^^^^^^^^^^^^^ number
Found 1 error
模块界限#
在跨模块使用的时候,Flow 需要明确注解。 为了保证 Flow 在各自模块内的独立检测,不去探测别的模块的调用,提高性能。 刚好这也提升了模块化编程中代码即文档的风格。
1 2 3 4 5 6 7 8 9 | /** * Size.js * @flow */ function size(input: string): number { return input.length; } module.exports = size; |
1 2 3 4 5 6 | /** * UseSize.js * @flow */ var size = require('./Size'); var result = size(null); |
Size.js
的 size
方法必须要类型注解,因为 UseSize.js
用到它,
因为不能夸模块探测,别的模块怎么使用我的方法我不知道,
所以我必须明确声明类型,暴露出去的时候,别人就知道我的要求了。
UseSize.js:6
6: var result = size(null);
^^^^^^^^^^ function call
6: var result = size(null);
^^^^ null. This type is incompatible with
5: function size(input: string): number {
^^^^^^ string. See: Size.js:5
Found 1 error
any
注解#
any
是一个特殊的类型注解,代表任何动态类型。
any
能够表示任何类型,当然也能接受任何类型。
any
就意味着 “别检查我,我知道我在干嘛”。
两个字#
你可以处处写上注解,这能充分表达你的代码意图。 不过 Flow 也有很多类型接口来减轻你的负担。 唯一必须要类型注解的就是模块间调用的资源。
You can edit this page on GitHub and send us a pull request!