TypeScript系列之-- 带你深层次理解联合&交叉类型(类型收窄)

联合类型

如果希望一个变量可以支持多种类型,就可以用联合类型(union types)来定义。

例如,一个变量既支持 number 类型,又支持 string 类型,就可以这么写:

type Nuion  = number | string
let num: Nuion = 1024
// 联合类型大大提高了类型的可扩展性,
//但当 TS 不确定一个联合类型的变量到底是哪个类型的时候,只能访问他们共有的属性和方法。
num.length //  报错
//如果直接访问 `length` 属性,string 类型上有,number 类型上没有,就报错了

交叉类型

如果要对对象形状进行扩展,可以使用交叉类型 &。

比如 Person 有 name 和 age 的属性,而 Student 在 name 和 age 的基础上还有 grade 属性,就可以这么写

interface Person {   
  name: string   
  age: number
}
type Student = Person & { grade: number }
//这和类的继承是一模一样的,这样 Student 就继承了 Person 上的属性,

联合类型 | 是指可以取几种类型中的任意一种,而交叉类型 & 是指把几种类型合并起来。

交叉类型和 interface 的 extends 非常类似,都是为了实现对象形状的组合和扩展。

类型收窄

如果有一个 getLength 函数,入参是联合类型 number | string,返回入参的 length。

从上文可知,这么写会报错,因为 number 类型上没有 length 属性

这个时候,类型收窄(Type Guards)出现了

使用typeof

const f1 = (a:number | string){
  if(typeof a === 'number'){
    a.toFixed()
  }else if( a === 'string'){
    a.split(',')
  }else{
    a
  }
}
// typeof无法区分对象的具体类型

const f1 = (a:Date | Array){
  typeof a  // 返回的都是object
}

使用Instanceof

const f1 = (a:Array<Date> | Date)>={
  if(a instaceof Date){
    a.getDay()
  }else if( a instanceof Array){
     a[0].getDay()
  }else{
     throw new Error('333') 
  }
}
// instaceof检索对象原型 不支持简单类型  string

以上两种不支持TS独有的类型,type | interface(因为类型擦除)

使用in 操作符

JavaScript 中有一个 in 操作符可以判断一个对象是否有对应的属性名。TypeScript 也可以通过这个收窄类型。

只适用于普通对象

type Person = {
  name: string
}
const f1 = (a:Person | Person[]) =>{
  if('name' in a ){
    a // Persion
  }else{
    a //Persion[]
  }
}

还可以使用JS中的isArray等方法。。。(以上方法都是用JS实现的,但JS的类型系统很鸡肋)

使用类型谓词/is

type Person {
  age:number
  height:number
}

type Aninal {
  width:[number,number]
  num:number
}
const f1 (a:Person | Aninal):boolean{
  if(isPerson(a)){
    a // 此处a就是Person类型
  }
  
}

function isPerson(b:Person | Aninal): b is Person{
  return 'age' in Person && 'height' in Person
}
//is支持所有对象类型  但缺点就是写起来太麻烦。。。还不容易理解

参考资料:

类型收窄_TypeScript中文文档

相关推荐

  1. 联合类型交叉类型

    2024-07-18 12:24:01       27 阅读
  2. TypeScript中的交叉类型

    2024-07-18 12:24:01       29 阅读
  3. TypeScript系列TypeScript 基础类型

    2024-07-18 12:24:01       29 阅读
  4. TypeScript类型推断

    2024-07-18 12:24:01       41 阅读
  5. TypeScript系列】缩小类型范围

    2024-07-18 12:24:01       35 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-18 12:24:01       66 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-18 12:24:01       70 阅读
  3. 在Django里面运行非项目文件

    2024-07-18 12:24:01       57 阅读
  4. Python语言-面向对象

    2024-07-18 12:24:01       68 阅读

热门阅读

  1. CPU响应pcie的中断,是否需要轮询

    2024-07-18 12:24:01       23 阅读
  2. 导航目录:掌握 `cd` 命令的技巧

    2024-07-18 12:24:01       22 阅读
  3. python常用内置数据类型

    2024-07-18 12:24:01       17 阅读
  4. 支付平台系统遭遇黑客攻击怎么办

    2024-07-18 12:24:01       23 阅读
  5. MySQL 实现模糊匹配

    2024-07-18 12:24:01       23 阅读
  6. Linux 驱动开发

    2024-07-18 12:24:01       25 阅读
  7. LeetCode 227. 基本计算器 II

    2024-07-18 12:24:01       22 阅读
  8. 如何实现MySQL的高可用

    2024-07-18 12:24:01       23 阅读
  9. docker安装指导

    2024-07-18 12:24:01       20 阅读
  10. 使用lxml库提取HTML中a标签的href和文本内容

    2024-07-18 12:24:01       22 阅读
  11. 一些数据库专家称,最新的 MySQL 版本令人失望

    2024-07-18 12:24:01       25 阅读