Flow静态类型检查方案

Flow定义

FlowJavaScript的类型检查器,使得写代码的效率更高效,Vue.js 的源码利用了 Flow 做了静态类型检查,所以了解 Flow 有助于我们阅读源码

添加类型注解的方式标记代码变量或参数的类型

Flow安装使用
  1. yarn init --yes初始化项目
  2. yarn add flow-bin --dev flow类型检查模块
  3. js文件开头需添加@flow注解
  4. 关闭vsCode JS校验 javascript:validate
  5. yarn flow init创建.flowconfig配置文件
  6. 执行yarn flow
编译

运行时移除类型注解

  • 使用官方flow-remove-types工具

    安装yarn add flow-remove-types --dev

    创建src目录

    yarn flow-remove-types src -d dist

  • 使用babel配合flow转换插件

    安装yarn add @babel/core @babel/cli @babel/preset-flow --dev

    .babelrc文件中添加 presets:[@babel/preset-flow]

    yarn babel src -d dist

开发插件(Flow language Support)

官方插件

类型推断
// @flow
// 通过变量的使用上下文来推断出变量类型,然后根据这些推断来检查类型
function square (n) {
  return n * n
}
// square('100')
square(100)
类型注解
// @flow
// 事先注释好我们期待的类型,Flow 会基于这些注释来判断
function square (n: number) {
  return n * n
}
let num: number = 100
// num = 'string' // error
function foo (): number {
  return 100 // ok
  // return 'string' // error
}
function bar (): void {
  // return undefined
}
原始类型
// 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]
对象类型
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
})
特殊类型
// 字面量类型
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
// @flow
// Mixed类型为具体类型 安全的 如果未标明是哪个类型 无法调用具体方法
function passMixed (value: mixed) {
  if (typeof value === 'string') {
    value.substr(1)
  }
  if (typeof value === 'number') {
    value * value
  }
}
passMixed('string')
passMixed(100)

// any是弱类型 不安全的 直接调用方法不会报错
function passAny (value: any) {
  value.substr(1)
  value * value
}
passAny('string')
passAny(100)
运行环境API
// @flow
// 如果查到返回HTMLElement 查询不到返回null
// document.getElementById('app') 必须传入字符串
const element: HTMLElement | null = document.getElementById('app')
FLowVue.js源码中的应用
  • libdef概念

    包含第三方库声明的JS文件简称,可以用于识别第三方库或者自定义类型;不然引入的第三方库,Flow检查时会抛出错误

    // @flow
    ...
    const s = $('id').hide() // 由于Flow并不认识$, 所以会报错,此时需要引入jQuery的库定义
    ...
    
  • 使用flow-typed解决

    1. 通过yarn add flow-typed安装flow-typed仓库,包含众多流行的第三方库的libdef
    2. 在项目根目录下创建flow-typed文件,并且下载对应的定义文件
    3. 运行flow-typed install检查package.json文件,下载项目中用到的第三方库的libdef
    4. 下载完成,yarn flow就没有错误了
    5. 如果用的库在flow-typed找不到,需要自定义libdef
  • Vue.js源码

    主目录的.flowconfig文件,是Flow的配置文件,Vue.js自定义类型都在里面定义。[libs]用来描述包含指定库定义的目录,默认是flow-typed目录,Vue.js指定未flow,表示指定的库定义在flow文件夹,目录如下:

    flow
    ├── compiler.js        # 编译相关
    ├── component.js       # 组件数据结构
    ├── global-api.js      # Global API 结构
    ├── modules.js         # 第三方库定义
    ├── options.js         # 选项相关
    ├── ssr.js             # 服务端渲染相关
    ├── vnode.js           # 虚拟 node 相关
    

    Vue.js自定义类型都定义在这里,遇到看不懂的类型,就需要翻阅这些数据结构的定义。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容