美文网首页
Flow(二)—— 简单语法使用

Flow(二)—— 简单语法使用

作者: 顽皮的雪狐七七 | 来源:发表于2020-12-01 00:04 被阅读0次

    目录

    • Flow类型推断
    • Flow类型注解使用的地方
    • Flow Type Annotations
      • 类型参考网址
      • 原始类型
      • 数组类型
        • 元组 —— Tuple Types
      • 对象类型
        • 通用写法
        • 添加可选属性
        • Map类
        • 混合使用
      • 函数类型
        • 函数参数
        • 可选函数参数
        • Rest参数
        • 函数返回
      • 特殊类型
        • 字面量类型
        • maybe类型
      • Mixed 与 Any
        • Mixed
        • Any
        • 两者的区别
    • Flow运行环境API

    之前写了Flow的相关介绍,如果想回顾的参考 Flow(一)—— JavaScript静态类型检查器
    ,这里简单的介绍Flow的语法,了解Flow的意义是在第三方源码中可以看到Flow的使用情况,可以帮助我们更好的了解源码。

    Flow类型推断

    没有执行变量类型,但是可以根据代码的使用情况推断类型,就叫类型推断

    // @flow
    // 因为字符串不能进行乘法运算,所以也会报错
     function square (n) {
       return n * n
     }
    
     square('100')
    
    image

    不过虽然有类型推断,但是建议开发者每个都添加类型,这样有可读性。

    Flow类型注解使用的地方

    绝大多数flow都可以推断出变量类型,但是并不意味着我们不需要给每个变量添加类型注解。添加类型注解可以明确去限制类型,而且对我们之后理解这里的代码很有帮助,建议尽可能的去使用类型注解

    • 类型可以标注的地方
      • 函数参数
      • 变量
      • 函数返回值
    // @flow
    // 函数参数标注类型注解
    function square (n: number) {
       return n * n
    }
    
    // 变量标注类型注解
    let num: number = 100
    
    // 函数返回值标注类型注解
    function foo (): number {
       return 100
    }
    // 上面那种情况,如果没有返回值,默认返回undefind,上面也会报错
    // 所以如果没有返回值,需要将返回类型标记为void
    function foo1 (): void {
       
    }
    

    Flow Type Annotations

    类型参考网址

    原始类型

    // @flow
    
     // 字符串
     const a: string = 'foobar'
    
     // 数字
     const b1: number = 100
     const b2: number = NaN
     const b3: number = Infinity // 无穷大
    
     // 布尔
     const c1: boolean = true
     const c2: boolean = false
    
     // null
     const d: null = null
    
     // undefined
     const e: void = undefined
    
     // symbol
     const f: symbol = Symbol()
    

    数组类型

    // @flow
    // 写法一:Array后面要添加泛型参数,number指定全部由数字组成的数组,如果有其他类型就会报错
     const arr1: Array<number> = [1, 2, 3]
     const arr2: Array<mixed> = [1, true, "three",{a:'1',b:2}]
    // 写法二:
     const arr3: number[] = [1, 2, 3]
    

    除了这种数组写法,还有一种特殊的固定长度的数组,我们称为 —— 元组

    元组 —— Tuple Types

    • 固定长度数组,如果改变长度会报错
    • 下标对应的元素必须是规定类型,设置新值得时候也必须匹配
    • 元组不匹配Array类型,因为数组类型长度不确定
    • 不能再元组上使用变异数组的方法,例如:copyWithinfillpoppushreverseshiftsortspliceunshift
    // @flow
    // 元组 —— 固定长度的数组
     // 下面的数组规定了两个元素,如果改变长度就会报错,而且下标对应的元素必须是规定的类型
     const arr4: [string, number] = ['foo', 100]
     arr4[2] = 1 // Cannot assign `1` to `arr3[2]` because  tuple type [1] only has 2 elements, so index 2 is out of bounds.
     const item0: string = arr4[0] // Works!
     const item1: number = arr4[0] // Cannot assign `arr3[0]` to `item1` because  string [1] is incompatible with  number [2]
    

    对象类型

    通用写法

    确定一个对象中键值有哪些,并且每个是什么类型

    // @flow
     const obj1: { foo: string, bar: number} = { foo: 'string', bar: 100}
     
    // 如果访问了obj1中没有的属性,原来会返回undefined,现在直接当做类型报错
     obj1.baz // Cannot get `obj1.baz` because property `baz` (did you mean `bar`?) is missing in  object type [1]
    

    添加可选属性

    可选属性可以是undefined或者省略,但是不能是null

     // foo如果可有可无,那么在foo后面加一个问号
     // 可选属性可以是undefined或者省略,但是不能是null
     const obj2: { foo?: string, bar: number} = { bar: 100}
     obj2.foo = undefined // Works!
     obj2.foo = null // Cannot assign `null` to `obj2.foo` because  null [1] is incompatible with  string [2]
    
    

    Map类

    键的类型用方括号

     // 初始化为空,可以自己添加键值对,规定键是string类型,值也是string类型
     const obj3: { [string] : string } = {}
    
     obj3.key1 = 'value1'
     obj3.key2 = 100 // annot assign `100` to `obj3.key2` because  number [1] is incompatible with  string [2]
    

    混合使用

    Map类和普通可以混合使用

    // @flow
    var obj: {
      size: number,
      [id: number]: string
    } = {
      size: 0
    };
    
    function add(id: number, name: string) {
      obj[id] = name;
      obj.size++;
    }
    

    函数类型

    一般是指参数类型和返回值类型进行类型注解

    函数参数

    // @flow
    
    // 参数输入确定类型
     function square (n: number) {
       return n * n
     }
    

    可选函数参数

    function func1 (num?: number) {
        const n = num ? num : 1
        console.log(n)
     }
    
     func1()  // 1  可以接受undefined,不能接受null
     func1(2) // 2
     func1(null) // Error!
    

    Rest参数

    // @flow
    function method(...args: Array<number>) {
      // ...
    }
    
    method();        // Works.
    method(1);       // Works.
    method(1, 2);    // Works.
    method(1, 2, 3); // Works.
    

    函数返回

    // 返回值确定类型
     // 有返回值
     function foo (): number {
       return 100
     }
     // 无返回值
     function foo1 (): void {
       
     }
    
    // 回调函数参数和返回值类型 
     function func (callback: (string, number) => void) {
       callback('string', 100)
     }
    
     func(function (str, n) {
       // str => string
       // n => number
       // 无返回值
     })
    

    特殊类型

    字面量类型

    与传统类型不同,这种字面量类型必须限制变量必须是某个值,一般不会单独使用,会配合 联合类型 去组合几个特性的值

    // @flow
    // 下面定义了n字面量,值只能是存放foo字符串,不能换成别的字符串和别的类型
    const n: 'foo' = 'foo'
    // 只能是下面三个字符串类型中的一种(下面的就是联合类型,也成或类型)
    const type : 'success' | 'warning' | 'danger' = 'success'
    // b变量既可以是string也可以是number,可以是字符串也可以是数字
    const b: string | number = 'string' // 100 
    
    
    // 也可以自己定义一个类型,StringOrNumber是一个类型的别名
    type StringOrNumber = string | number
    const test: StringOrNumber = 'string' // 100
    

    maybe类型

    有可能,在基本类型的基础上扩展了nullundefined的类型

    // @flow
    // 添加?可以使用null和undefined
    const gender: ?number = null
    const gender1: ?number = undefined
    const gender2: ?number = 100
    
    // 相等于下面的number或null或undefined
    const gender: number | null | void = undefined
    

    Mixed 与 Any

    Mixed

    Mixed可以接收任意类型的值,是所有类型的联合类型string | number | boolean | ...

    // 参数是mixed类型
    function passMixed (value: mixed) {
      console.log(value)
    }
    
    passMixed('string') // string
    passMixed(100) // 100
    

    Any

    Mixed一样,可以接收任意类型的值

    function passAny (value: any) {
        console.log(value)
    }
    
    passAny('string') // string
    
    passAny(100) // 100
    

    两者的区别

    • Mixed是一个强类型,如果有使用隐患的话就会报错,只能用typeof进行类型判断
    • Any是一个弱类型,如果有使用隐患,语法上不会报错。
    • Mixed是安全的(推荐使用),Any是不安全的,存在的意义是为了兼容老代码
    // Mixed
    // 如果没有明确这个变量是字符串还是数字,那么不能直接进行使用的,会报错
    function passMixed (value: mixed) {
      console.log(value)
      value = value ** 2 // Cannot perform arithmetic operation because  mixed [1] is not a number.
    }
    
    // 如果想要 解决上面的问题,需要使用typeof进行类型判断
    function passMixed (value: mixed) {
      if (typeof value === 'string') {
        value.substr(1)
      }
      if (typeof value === 'number') {
        value ** 2
      }
    }
    
    
    // Any
    // 下面语法上是不会报错的, 运行阶段不确定
    function passAny ( value: any) {
      value = value ** 2
    }
    

    Flow运行环境API

    JavaScript需要运行在某个环境中,例如:浏览器环境或者node环境。
    他们有本身自己的API,如浏览器中的DOMBOMnode中的path等,我们在flow中也会使用到这些对象。

    那么这些有特殊的类型限制,例如:

    document.getElementById() //里面参数传字符串,数字会报错
    // 这是浏览器环境内置的API的一些限制
    document.getElementById('app') //返回对应的类型是HTMLElement
    // 如果没有找到对应元素,也返回null类型,那么接收的时候可以这么写
    const element: HTMLElement | null = document.getElementById('app')
    

    右键跳到定义可以看到,原生里面有定义

    image

    官网仓库给出了一些类型声明,开发的时候可以参考使用

    相关文章

      网友评论

          本文标题:Flow(二)—— 简单语法使用

          本文链接:https://www.haomeiwen.com/subject/duxjwktx.html