一、背景
首先介绍一下什么是flow , 一个 JAVASCRIPT 静态类型检测器 为什么js 要进行类型检测? 对于javasscrip 来说,JavaScript 是一种弱类型(或称动态类型)语言,即变量的类型是不确定的。
x = 5; // 5
x = x + 'A'; // '5A'
优点-灵活,代码简洁 缺点-不利于发现类型错误,存在数据隐患,经常会遭到接触过后端语言同学的吐槽
二、目前转化成强类型的方法
- TypeScript 是微软2012年推出的一种编程语言,属于 JavaScript 的超集,可以编译为 JavaScript 执行 为什么没有采用TypeScript 的方式,主要有以下几方面考虑
- 虽然语法与javascript有很多相似的地方,但是总归是一门新的语言类型,相对来说有一定的学习成本
- 项目比较成熟,javascript 迁移TypeScript 相对工作量以及改动比较大
- 虽然vue2.0 已经支持了TypeScript的方式,但是不能保证我们应用的所有的组件库都对此语法支持,为避免后期又不确定的麻烦
- Flow 是 Facebook 在2014年发布的一个类型检查工具
- 安装简单
- 相对没有学习成本
- 对已经成熟的项目改动较小
- 支持eslint 检测
- vue 源码采用的Flow 类型检测的方式
三、flow 的引入
1. 安装包
yarn add flow-bin @babel/preset-flow -D
2. 生成flow 文件
flow init
会生成一个.flowconfig 文件,修改文件配置
[ignore]
.*/node_modules/.*
.*/test/.*
.*/build/.*
.*/config/.*
[include]
[libs]
[options]
module.file_ext=.vue
module.file_ext=.js
3. 执行flow
在文件头部写入/* @flow */
或者 // @flow
弱模式: /* @flow weak */
,在弱模式下,Flow 就不做那么多类型检测, 对方法内的类型还是会探测,但是对其他未注解的变量,会认为他们可以是 any 任何类型——也就意味着无须检测,适合项目初期
然后运行 flow check
或者 yarn run flow
我们会看到文件报错信息,表明项目已经安装flow 成功
4. 修改babel
修改.babel/babel.config.js 文件,添加@babel/preset-flow,这样babel 在编译的时候会移除 Flow 注解,把添加类型检测的文件转化成浏览器可支持的语法
presets: [
'@babel/preset-flow'
]
5. 添加eslint 代码检测 eslint-plugin-flowtype
yarn add eslint-plugin-flowtype -D
修改.eslintrc.js 文件
extends: [
'plugin:flowtype/recommended',
],
rules: [
'flowtype/require-parameter-type': 2,
'flowtype/generic-spacing': 2
},
....
plugins: ['flowtype'],
settings: {
flowtype: {
onlyFilesWithFlowAnnotation: true //只在添加@flow注释的文件才做检查
}
}
四、flow 使用方式简介
1. 类型注释 / 类型注解
在大多数情况下,Flow 都能够探测出具体类型,所以你不需要给每个方法、变量都添加类型注解。 虽说 Flow 能探测出类型,但是你依然可以严格声明类型。 只有下面这类情况才 必须 明确地声明类型:变量/方法/类 是从别的模块中导入的(在别的文件定义)
// @flow
(function() {
function foo(x: string, y: number): string {
return x.length * y;
}
foo('Hello', 42);
});
这表示 foo 方法返回值的类型为 string,并且两个参数类型分别为 string 和 number
2. 原生数据类型
boolean、number、string、null、void 此处需要注意 上面的类型属性 与 Number, String, Boolean是有本质的区别的,我们通过代码来看一下 代码类型为小写,表示常规类型
// @flow
function method(x: number, y: string, z: boolean) {
// ...
}
method(3.14, "hello", true);
代码类型为大写,表示对象类型
// @flow
function method(x: Number, y: String, z: Boolean) {
// ...
}
method(new Number(42), new String("world"), new Boolean(false));
3. 未确定类型(Maybe types)
我们可以使用type 用 ?type, 表示此类型可能为type 类型,也有可能是 null or void.
// @flow
function acceptsMaybeString(value: ?string) {
// ...
}
acceptsMaybeString("bar"); // Works!
acceptsMaybeString(undefined); // Works!
acceptsMaybeString(null); // Works!
acceptsMaybeString();
如果是对象类型的,我们可以使用 { propertyName?: string }
4. 泛型
泛型对象可以使用别名类型来定义
type GenericObject<T> = { foo: T };
var numberObject: GenericObject<number> = { foo: 0 };
var stringObject: GenericObject<string> = { foo: "foo" };
这里只介绍常规的使用方法以及 API ,详细内容还需要大家看文档
五、报错处理
1. types' can only be used in a .ts file
如果使用的vscode 我们在只从过程中可能会遇到 此问题,
解决办法: 关闭vs code 的检测
"javascript.validate.enable": false