flow js 类型检查器

如何使用Flow

初始化 yarn init —yes
安装 yarn add flow-bin —dev (这是是局部安装的)
在flow的 bin下 找到 flow 可执行文件
使用了flow 就不需要 vscode的js 语法校验了
关闭 vscode 语法校验:打开 设置 搜索 javascript validate 关闭
使用flow
需要在 使用 flow的 文件内 添加 // @flow 的标记
此时yarn flow 会报错 因为没有初始化
初始化 yarn flow init
再次 使用 yarn flow 就ok了
完成后 可以使用 yarn flow stop 命令 结束服务

测试代码_

  1. // @flow
  2. function sum (a: number, b: number) {
  3. return a + b
  4. }
  5. sum(100, 100)
  6. // 使用flow 找到了 类型使用上的问题
  7. // sum('100', '100')
  8. // sum('100', 100)

运行时发现 我们无法通过node 直接运行
因为 运行时必须要 去掉类型注解
我们需要安装模块来 进行操作

方式1:

可以通过 flow-remove-types 模块 来去除类型注释
安装 —— yarn add flow-remove-types —dev
执行 ——- yarn flow-remove-types {当前目录} -d {输出目录}
如: yarn flow-remove-types . -d dist
可以在 dist 中 找到 我们编译的文件

方式2:

也可以安装 babel 来进行
安装 先安装@babel/core 核心模块
安装 @babel/cli 工具 可以在命令行直接使用 babel命令完成编译
安装 @babel/perset-flow 包含了转换flow 类型注解的插件
先在项目中 添加一个 babel的配置文件 .babelrc
babelrc中 添加presets 这里的 presets 就是我们刚刚添加的 @babel/preset-flow

插件:

开发工具插件 Flow Language Support
可以直接显示出来 当前的类型问题
必须保存过后才会重新检测

类型推断

  1. /**
  2. * 类型推断
  3. *
  4. * @flow
  5. */
  6. function square (n) {
  7. return n * n
  8. }
  9. // 传入非数字参数 flow 仍然可以发现 类型错误 ----类型推断
  10. // 尽可能 为代码中的成员去添加 类型注解 有更好的可读性
  11. // square('100')
  12. square(100)
  13. // square('100') 此处报错

类型注解

  1. /**
  2. * 类型注解
  3. *
  4. * @flow
  5. */
  6. // 参数应用
  7. function square (n: number) {
  8. return n * n
  9. }
  10. // 变量名上应用
  11. let num: number = 100
  12. // num = 'string' // error
  13. // 返回值应用
  14. function foo (): number {
  15. return 100 // ok
  16. // return 'string' // error
  17. }
  18. // 没有返回值 默认返回 undefined
  19. function bar (): void {
  20. // return undefined
  21. }

原始类型

  1. /**
  2. * 原始类型
  3. *
  4. * @flow
  5. */
  6. const a: string = 'foobar'
  7. // Infinity 无穷大
  8. const b: number = Infinity // NaN // 100
  9. const c: boolean = false // true
  10. const d: null = null
  11. // flow 中 undefined 用 void 标记的
  12. const e: void = undefined
  13. const f: symbol = Symbol()

数组类型

  1. /**
  2. * 数组类型
  3. *
  4. * @flow
  5. */
  6. const arr1: Array<number> = [1, 2, 3]
  7. const arr2: number[] = [1, 2, 3]
  8. // 元组 固定长度的数组
  9. const foo: [string, number] = ['foo', 100]

对象类型

  1. /**
  2. * 对象类型
  3. *
  4. * @flow
  5. */
  6. // 此对象必须具有foo和bar 两个成员 而且类型必须匹配
  7. const obj1: { foo: string, bar: number } = { foo: 'string', bar: 100 }
  8. // ?代表可选
  9. const obj2: { foo?: string, bar: number } = { bar: 100 }
  10. // 指定键值的类型
  11. const obj3: { [string]: string } = {}
  12. obj3.key1 = 'value1'
  13. obj3.key2 = 'value2'

函数类型

  1. /**
  2. * 函数类型
  3. *
  4. * @flow
  5. */
  6. // 设置回调函数返回值 及参数
  7. function foo (callback: (string, number) => void) {
  8. callback('string', 100)
  9. }
  10. foo(function (str, n) {
  11. // str => string
  12. // n => number
  13. // 不可有返回值 或者返回 undefined
  14. })

特殊类型

  1. /**
  2. * 特殊类型
  3. *
  4. * @flow
  5. */
  6. // 字面量类型
  7. // 限制变量必须是某一个值
  8. const a: 'foo' = 'foo'
  9. // 联合类型 或类型
  10. const type: 'success' | 'warning' | 'danger' = 'success'
  11. // ------------------------
  12. // 声明类型
  13. type StringOrNumber = string | number
  14. const b: StringOrNumber = 'string' // 100
  15. // ------------------------
  16. // Maybe 类型
  17. const gender: ?number = undefined
  18. // 相当于
  19. // const gender: number | null | void = undefined

Mixed/Any

  1. /**
  2. * Mixed Any
  3. *
  4. * @flow
  5. */
  6. // string | number | boolean | .... 可以是任何类型
  7. function passMixed (value: mixed) {
  8. // 需要加判断 不然会报语法错误
  9. if (typeof value === 'string') {
  10. value.substr(1)
  11. }
  12. if (typeof value === 'number') {
  13. value * value
  14. }
  15. }
  16. passMixed('string')
  17. passMixed(100)
  18. // ---------------------------------
  19. // any 也可以传入任意类型的参数
  20. // any 弱类型 mixed 强类型
  21. function passAny (value: any) {
  22. value.substr(1)
  23. value * value
  24. }
  25. passAny('string')
  26. passAny(100)
  27. // 第三方 flow 文档
  28. // https://www.saltycrane.com/cheat-sheets/flow-type/latest/