FLOW概述
JavaScript静态类型检查器。2014年Facebook推出的工具。 使用它就可以弥补一些弱类型带来的弊端。提供了更完善的类型系统
在代码中标记类型注解来标明什么类型
function square (n: number) {
return n * n
}
在代码中这些额外的类型注解,在运行之前,可以通过Babel或者FLOW官方提供的一个模块自动去除,在生产环境中,这些类型注解不会有任何的影响
ps:flow并没有强制要求每一个地方都要加上类型注解,完全可以在需要的地方添加:
function sum (a: number, b) {
// a: number
// b: any
return a + b
}
flow充其量只是一个小工具。
flow快速上手
可以使用npm或者yarn来安装flow
yarn add flow-bin --dev
安装完之后,输入指令:
yarn flow init
这个命令会生成一个.flowconfig的配置文件,里面有一些初始的配置选项。后续再说
接着就可以执行flow命令了:
yarn flow
第一次执行会相对慢一点,会启动一个后台服务去接受文件
完成编码工作之后,可以使用
yarn flow stop
就可以停止flow服务。执行之后就会找到一些你的类型错误,比如这样:
[!IMPORTANT]
注意:在需要flow进行类型检查的文件中添加一个@flow的标志。
flow移除类型注解
yarn flow-remove-types . -d dist
也可以使用第三方的babel进行操作:
yarn add @babel/core @babel/cli @babel/preset-flow
安装好之后新建一个babelrc文件:
// .babelrc
{
"presets": ["@babel/preset-flow"]
}
yarn babel src -d dist
这样就可以运行起来了,也是一样的类型注解去除效果
flow开发编辑器插件
类型推断
所谓的类型推断,就是没有写类型注解的情况下,flow会根据你调用的情况来判断他是什么类型的,在其他地方如果有不符合他判断的类型的操作,就会报错:
/**
* 类型推断
*
* @flow
*/
function square(n) {
return n * n;
}
// 比如这里就会报错,字符串不支持相乘
square("100");
类型
flow的大部分类型和Typescript的写法基本一致,没有什么特别需要拿出来说的,所以我们一笔带过:
原始类型
/**
* 原始类型
*
* @flow
*/
const a: string = 'foobar'
const b: number = Infinity // NaN // 100
const c: boolean = false // true
const d: null = null
const e: void = undefined
const f: symbol = Symbol()
数组类型
/**
* 数组类型
*
* @flow
*/
const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
// 元组
const foo: [string, number] = ['foo', 100]
对象类型
/**
* 对象类型
*
* @flow
*/
const obj1: { foo: string, bar: number } = { foo: 'string', bar: 100 }
const obj2: { foo?: string, bar: number } = { bar: 100 }
// 键值对。键是字符串,值是字符串。
const obj3: { [string]: string } = {}
obj3.key1 = 'value1'
obj3.key2 = 'value2'
函数类型
/**
* 函数类型
*
* @flow
*/
function foo (callback: (string, number) => void) {
callback('string', 100)
}
foo(function (str, n) {
// str => string
// n => number
})
特殊类型
/**
* 特殊类型
*
* @flow
*/
// 字面量类型
const a: 'foo' = 'foo'
const type: 'success' | 'warning' | 'danger' = 'success'
// ------------------------
// 声明类型
type StringOrNumber = string | number
const b: StringOrNumber = 'string' // 100
// ------------------------
// Maybe 类型
const gender: ?number = undefined
// 相当于
// const gender: number | null | void = undefined
Mixed & any
/**
* Mixed Any
*
* @flow
*/
// string | number | boolean | ....
function passMixed (value: mixed) {
if (typeof value === 'string') {
value.substr(1)
}
if (typeof value === 'number') {
value * value
}
}
passMixed('string')
passMixed(100)
// ---------------------------------
function passAny (value: any) {
value.substr(1)
value * value
}
passAny('string')
passAny(100)
Mixed和any的区别就在于,any是弱类型,Mixed是强类型,Mixed在没有明确知道具体的值的类型的时候是会报错的。而any就不会
Flow运行环境API
JavaScript必须要运行在特定的运行环境,比如Browser和Node,运行环境一定会提供API使用
/**
* 运行环境 API
*
* @flow
*/
const element: HTMLElement | null = document.getElementById('app')
就比如document.getElementById这个API就会返回HTMLElement或者null类型