为何要使用flow
因为js弱类型且 动态类型的语言
弱类型:代码内部允许进行隐式类型转换
动态类型语言:
1、在运行阶段,才能明确一个变量的类型,且变量的类型随时可以改变
2、也就是说,在动态类型语言中,变量没有类型,变量中存放的值有类型
因为该特点,导致JS代码有一些问题只有在运行时才能暴露出问题,编译时不可预知到问题所在
而flow在代码编写阶段就为我们提供了静态类型检测的能力
flow语法参考文档:flow语法
如何使用flow:
flow是一个帮我们进行JS数据类型检测的小工具
-
因为flow是需要以npm包的形式安装的,因此在项目中初始化一个package.json 用来管理依赖 使用npm init
-
通过 npm i flow-bin -dev 安装flow到我们的项目中(开发依赖即可)
npm i flow-bin -dev
或使用yarn
yarn add flow-bin --dev
我们使用的是npm, 安装完之后可以在node_modules/.bin 下找到flow这个可执行文件
-
在package.json中添加一条命令:就可以使用 npm run flow来进行类型检测
"flow":"flow"
-
在终端运行 npm flow init 用于初始化 .flowconfig文件
-
在需要flow进行检测的文件 起始位置添加 //@flow,以使flow工具确认要检测的文件
- npm run flow 运行flow命令,看下效果
flow编译移除注解
flow添加注解的方式 不是标准的javascript语言,在使用这个js文件会有问题的,因此需要编译工具去除掉我们的注解
-
安装babel
npm i @babel/core @babel/cli @babel/preset-flow -dev
-
创建.babelrc文件,并添加以下内容
{ "presets": ["@babel/preset-flow"] }
-
package.json中添加一条命令
一般待编译的源码放在项目 src文件夹下, dist文件夹放置编译好的文件
该命令的作用就是将src 目录下的所有文件编译输出到dist文件夹中
"build_flow": "babel ./src -d ./dist"
编译好的文件就是我们可以使用的js文件:
声明变量是添加类型注解
let n : number = 100
n = 'string' //变为不是number类型,会报错
function foo( ): number { //声明函数的返回值类型
return 100
}
//如果函数没有返回值:
function bar(): void {
......
}
Flow 原始数据类型
const a: string = 'foot'
const b: number = Infinity // NaN // 100(普通数值)
const c: boolean = false //true
const d: null = null
const e: void = undefined
const f: symbol = Symbol()
Flow数组类型
//arr1和arr2都表示数组中只能存放数字类型
const arr1: Array<number> = [1,2,3]
const arr2: number[] = [1,2,3]
//限定数组长度及内容类型
const foo: [string, number, number] = ['luffy', 18, 28]
flow对象类型
//表示对象中必须有foo和age属性,且数据类型必须与规定的一致 ?:表示该变量可有可无
const obj1:{ foo: string, age: number, location?: string} = {
foo:'luffy',
age:19
}
//obj3 允许添加任意多个键和值,但是键和值都必须是字符串类型
const obj3: {[string]: string} = {}
flow函数类型
//限定回调函数有两个参数 分别是string和number 且callback是没有返回值得
function foo (callback: (string, number) => void) {
callback('string', 100)
}
foo(function(str, n){
})
特殊类型
//字面量类型,表示变量必须是某一个值
//表示变量a只能是字符串'foo'
const a :'foo' = 'foo'
//字面量类型一般不会单独只指定一个值,一般通过联合类型使用
//表示type必须是三个当中的一个
const type: 'success' | 'warning' | 'error' = 'success'
//联合类型:
//表示变量b可以使数字或布尔值
const b: number | boolean = 1
//type关键字创建自定义类型
type NumberOrBoolean = number | boolean
const c: NumberOrBoolean = true
//Maybe类型
//?表示可以是null或undefined
const myNumber: ?number = undefined
Mixed & Any
//mixed 表示可以接收任意数据类型,是什么都可以
function passMixed(a: mixed){
//不可以直接对a进行操作,要先判断类型
//错误操作
a.slice(0,2)
a * a
//正确操作:
if(typeof a ==='string'){
a.slice(0,2)
}
if(typeof a ==='number'){
a * a
}
}
passMixed(100)
passMixed('string') //都没有问题
//any同样可以接收任意数据类型
function passAny(a: any){
//直接调用字符串方法
a.slice(0,2)
//直接调用数字方法
a * a
}
passAny(100)
passAny('string') //都没有问题
//any 与 mixed区别:
//any是弱类型,在函数内部可以对参数进行任何操作
//mixed依旧是强类型,在函数内部进行操作室需要先判断传入的数据类型才能继续操作