TypeScript最近大火,很多人在说它与JavaScript不同之处,其中有一点必提的就是类型检查。如果我不想用TS写代码,还想对原生的JavaScript做类型检查,有没有这样的工具包呢?
FLow:https://flow.org/en/
Flow是由 facebook 开发的 JavaScript 静态类型检查工具。下面举几个例子,看看怎么使用。
安装使用
- npm init 生成 package.json
- npm install --save-dev @babel/core @babel/cli @babel/preset-flow
- 创建.babelrc,配置
{
"presets": ["@babel/preset-flow"]
}
- npm install --save-dev flow-bin
- 在package.json中的脚本中添加
"scripts": {
"flow":"flow",
}
- npm run flow init 初始化flow,生成.flowconfig
- 创建测试文件 test-flow.js,添加代码
function foo(x: ?number): number {
if (x) {
return x;
}
return 0;
}
foo('hi')
- 运行 npm run flow
类型检查成功!
几个例子
- 混合类型的检查
如果想要检查的类型可能是 string 也可能是 number 怎么办?Flow 也支持多种类型的检查。
function foo(value: string | number) {
return '' + value;
}
foo(123) // Works!
foo('hi') // Works!
foo(true) // Error!
- 可选类型
在代码中传递 null 和 undefined 的很常见的,如何在这种情况下检查类型呢。我们需要在类型前面加一个?,比如?number
// @flow
function foo(value: ?number) {
// ...
}
foo(42); // Works!
foo(); // Works!
foo(undefined); // Works!
foo(null); // Works!
foo("42"); // Error!
如果你的参数是一个对象,没有属性key,应该怎么合理检查呢?
// @flow
function foo({ value }: { value?: ?number }) {
// ...
}
foo({ value: undefined }); // Works!
foo({}); // Works!
- 类检查
// @flow
class Bar {
x: string;
y: string | number;
z: boolean;
constructor(x: string, y: string | number) {
this.x = x
this.y = y
this.z = false
}
}
var bar: Bar = new Bar('hello', 4)
- 自定义类型检查
像 Vue 、React 这样的框架不止有基本类型,肯定有自己定义的类型,那 Flow 是怎么执行检查的呢?
为了解决这类问题,Flow 提出了一个 libdef 的概念,可以用来识别这些第三方库或者是自定义类型。在.flowconfig 的 [libs] 部分用来描述包含指定库定义的目录。
Vue 就是采用 Flow 进行静态类型检查的,在源码目录下可以看到一个 .flowconfig 文件,[libs] 指向 flow 文件夹,打开文件夹,文件结构是:
flow
├── compiler.js # 编译
├── component.js # 组件
├── global-api.js # Global API
├── modules.js # 第三方库
├── options.js # 选项
├── ssr.js # 服务端渲染
├── vnode.js # 虚拟 node
├── weex.js # weex
可以看到,Vue.js 有很多自定义类型的定义。