【Typescript 系列】第七节:类型守卫语法

248 阅读3分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情

1. 引言

在上一期中,我们提到过TypeScript的类型守卫语法,今天我们来讲讲,什么是TypeScript的类型守卫语法,它有什么用?它在什么场景使用呢?让我们开始来一一探索解惑吧!

2. 含义

首先我们先来介绍下什么是类型守卫语法,顾名思义:“==类型守卫是一个真值缩小,确保在类型检测阶段该类型在对应合适的类型范围内,需要通过类型检测工具判断具体类型,才能保持运行正确。==” 那类型守卫都有哪些呢?

  1. in 关键字
  2. typeof 关键字
  3. instanceof关键字
  4. 自定义类型保护的类型谓词

3. 作用

可执行运行时检查的一种表达式,在检测阶段真值缩小/收窄 确保该类型在一定的范围内在被检测使用时对应具体使用类型时保证运行正确。

4. 例子

下面我们分别对应不同类型守卫语法来描述下他们具体内容:

  1. in 关键字
interface InfoObj {
  name: string
  sex: string
  age: number
}
interface ExtraObj {
  name: string
  address: string
}

function getInfo(arg: InfoObj | ExtraObj){
  console.log('姓名',arg.name) // ok
  console.log('性别',arg.sex) // error: Property 'sex' does not exist on type 'InfoObj | ExtraObj'.Property 'sex' does not exist on type 'ExtraObj'.
  console.log('地址',arg.address) // error: Property 'address' does not exist on type 'InfoObj | ExtraObj'.Property 'address' does not exist on type 'InfoObj'.
}

// 以上说明当我们使用联合接口类型作为函数的形参(形参和实参不懂得同学可以自行前往学习下)时,函数内部运行调用形参对应属性值,当它不确定传入的形参是否有对应类型时会报错,所以接下来我们使用in 关键字进行类型缩小就可避免这个问题了

function getInfo(arg: InfoObj | ExtraObj){
  if ('name' in arg) console.log('姓名',arg.name) // ok
  if ('sex' in arg) console.log('性别',arg.sex) // ok
  if ('address' in arg) console.log('地址',arg.address) // ok
}
  1. typeof 关键字 同理,使用时进行类型缩小就不会出现报错
function isString( val: string | number) {
    if (typeof val === "number") return 'number'
    if (typeof val === "string") return 'string'
    return 'unknown'
}

注意:typeof运算符的判断返回类型为字符串,值包括如下几种:

    1. 'undefined'              --未定义的变量或值

    2. 'boolean'                 --布尔类型的变量或值

    3. 'string'                     --字符串类型的变量或值

    4. 'number'                  --数字类型的变量或值

    5. 'object'                    --对象类型的变量或值,或者null(这个是js历史遗留问题,将null作为object类型处理)

    6. 'function'                 --函数类型的变量或值

    7. "symbol"                 --Symbol (ECMAScript 2015 新增)

  1. instanceof
function isDate(date: Date | string): any{
    console.log(date)
    if(date instanceof Date){
      date.getDate()
    }else {
      return new Date(date)
    }
}

  1. 自定义类型保护和类型谓词
function isNumber(numVal: any): numVal is number {
    return typeof numVal === 'number';
}
function isString(strVal: any): strVal is string{
    return typeof strVal=== 'string';
}

// 这种用法类似在形参声明阶段就定义好形参使用类型,并在函数运行使用阶段使用类型缩小

5. 总结

TypeScript 是一种强类型语言,因为受静态类型检测约束,所以在编码阶段我们必须使用类似的手段确保当前的数据类型支持相应的操作。当然,前提条件是已经显式地注解了类型的多态。在使用的过程中就需要显示地标明 操作 的类型就是 具体的什么类型,避免调用出错。