flow 一个js类型检查插件

911 阅读3分钟

前言

弱类型、强类型、动态类型、静态类型语言的区别是什么?

  • 强类型和弱类型语言:数据类型在定义赋值时 **是否要校验类型 **。强类型需要校验(typescript),弱类型不需要(JavaScript)
  • 动态类型和静态类型语言:动态类型会在运行时才检查类型错误(JavaScript),静态类型在编译时就会检查(typescript)。
  • 注意:不是弱类型语言就是动态类型,反之其他种类也是,两者之间没有任何关系

由于JavaScript是一门弱类型的语言,所以在某些情况下会发生一些不可预知的错误,如下列情况:

function sum(a, b) {
    return a + b
}
// 一般来说这个函数是用来求和的,但是当传入的参数都为字符串时,这个函数就不能返回预期的值
sum(5, 3) // 8
sum('5', '3') // 53

所以怎么去避免这个错误发生呢,在typescript中有着对应的类型检查,但是我们现在要在js文件中进行类型检查的话要怎么做呢?我们可以使用flow插件去实现这个功能,它的大部分使用规则跟typescript是一样的

如何安装flow

官方网址:flow.org/en/docs/ins…

1. 安装flow 

// 安装依赖包
npm install --save-dev flow-bin
// 配置编译的命令,在package.json里
{
    "name": "hello",
    "version": "1.0.0",
    "scripts": {
        "flow": "flow", // 新增这一行
    }
}
// 初始化flow的配置文件
npm run flow init
//运行编译命令
npm run flow

如果vscode自带的js校验flow语法报错的话,可以关闭vscode的检查,目录层级必须是全英文文件夹和文件,不然flow不支持。

vscode安装flow提示插件:应用商店搜索安装" Flow Language Support "。

在要使用flow语法的js文件添加注释 @flow ,这样编译的时候才会去编译对应的js文件

2.安装把带有flow语法的js文件打包成正常的js文件

// 第一种方法,安装插件 flow-remove-types
npm install flow-remove-types --save-dev

//第二种方法,安装babel插件
npm install --save-dev @babel/core @babel/cli @babel/preset-flow
//然后创建一个 .babelrc文件,配置参数
{
    "presets": ["@babel/preset-flow"]
}

3.如何打包去除flow的类型校验

// 使用flow-remove-types
// 配置编译的命令,在package.json里
{
    "name": "hello",
    "version": "1.0.0",
    "scripts": {
        "flow": "flow",
        "build": "flow-remove-types . -d dist" // 新增这一行,
        // "."代表当前目录,这里是放要编译哪个目录的文件,这里最好不要放当前目录,放在一个新建的src目录下
        // "dist"编译后的文件存放在哪个目录下
    }
}

// 使用babel
//配置编译命令,在package.json里
{
    "name": "hello",
    "version": "1.0.0",
    "scripts": {
        "flow": "flow",
        "build": "babel src -d dist" // 新增这一行
        // "src" 代表要编译的目录,如果用当前目录的话,会把node_modules的文件也给编译了
    }
}

flow的使用

  1. 对象类型

    // 必须含有name和age两个属性let obj: {name: string, age: number} = {name: 'sky', sex: '男'} // 报错,缺少age// 可选属性let obj2: {name?: string, age: number} = {age: 18, sex: '男'}// 键值约定let obj3: { [string]: string } = {}obj3.name = 'sky'obj3.age = 100 // 这里会报错,不能为number

2. mixed和any区别

/*mixed和any的区别,它们都表示可以为任意类型,但是:mixed是一个强类型,它不能随意调用不同类型的api或方法,必须先判断它为什么类型any是一个弱类型,它可以随意使用*/ function sum(a: mixed, b: mixed):void {  if(typeof a == 'string') {    a.substr(1)  }  if(typeof a == 'number' && typeof b == 'number') {    a + b  }}sum(5, 3)function sum1(a: any, b: any):void {  a.substr(1)  a + b}sum1(5, 3)

3.其他类型用法跟typescript一致