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类型

小结

官网类型文档
第三方类型手册

最后修改:2024 年 03 月 21 日
收款不要了,给孩子补充点点赞数吧