《七》TypeScript 中的枚举类型、映射类型和条件类型

枚举类型 enum:

枚举就是将一组可能出现的值,一个个列举出来,定义在一个类型中,使用 enum 关键字来定义,这个类型就是枚举类型。

枚举类型允许开发者定义一组命名的常量。

// 定义枚举类型
enum Direction {
  LEFT,
  RIGHT,
}

// 使用枚举类型
const turnDirection = (direction: Direction) => {
  switch (direction) {
    case Direction.LEFT:
      console.log('向左移动一个格子')
      break
    case Direction.RIGHT:
      console.log('向右移动一个格子')
      break
  }
}
turnDirection(Direction.LEFT)

枚举项的值:

枚举项默认会被赋值为从 0 开始递增的数字。请添加图片描述
可以给枚举项手动赋数字类型的值,正负数、整数浮点数都可以。未手动赋值的枚举项会接着上一个枚举项递增,递增步长为 1。

enum Direction {
  LEFT = -10.5,
  RIGHT,
}

请添加图片描述
也可以给枚举项赋字符串类型的值,但此时后面的枚举项就无法递增了,必须显式地赋值,否则就会报错。

enum Direction {
  LEFT, // 正确。给枚举项赋字符串类型的值后,前面的枚举项无须显式地赋值,默认值还是从 0 开始的数字
  RIGHT = 'right',
  UP, // 错误。给枚举项赋字符串类型的值后,后面的枚举项必须显式地赋值
}

请添加图片描述

映射类型:

有时候,一个类型需要基于另外一个类型,但是又不想手动拷贝一份,此时就可以使用映射类型。

映射类型必须使用 type 来定义,不能使用 interface。可以把映射类型想象成是一个函数,调用它之后就会拷贝出来一份类型。

// 1. 定义一个类型
type PersonType = {
  name: string,
  age: number,
}

// 2. 定义映射类型
// 使用 type 定义一个映射类型的名称,然后通过泛型接收一个类型,使其等于一个对象类型
type MapType<Type> = {
  // 基于索引签名。通过  keyof Type 拿到 Type 中的每个 key,然后依次作用一次,其实就相当于遍历了一次
  [property in keyof Type]: Type[property]

  // 其实就相当于:
  // name: PersonType['name'] --> string,
  // age:  PersonType['age'] --> number,
}

// 3. 调用映射类型拷贝出来一份类型
type newPersonType = MapType<PersonType>

请添加图片描述

映射类型的修饰符:

  1. ?:用于设置属性可选。
  2. readonly:用于设置属性只读。

拷贝的过程中可以使用修饰符对原来的类型进行转变。修饰符的前面还可以加 + 或者 - 的符号来表示添加或者删除修饰符,默认是 +

type PersonType = {
  name: string,
  age: number,
}

type MapType<Type> = {
  // 添加 ? 修饰符使得拷贝后的所有属性都变成可选属性
  [property in keyof Type]?: Type[property]

  // 就相当于是:
  // [property in keyof Type]+?: Type[property]
}

type newPersonType = MapType<PersonType>

请添加图片描述

条件类型:

条件类型用来帮助描述输入类型和输出类型之间的关系。语法类似于 JavaScript 中的三元运算符 someType extends OtherType ? TrueType : falseType,根据前面的条件来决定返回哪个结果。

type IDType = number | string
type resType = number extends IDType ? true : false 
// 参数只能接受 number 类型和 string 类型,并且必须同时为 number 类型或者 string 类型;返回值如果不是 number 类型,就是 string 类型
function sum<T extends number | string>(num1: T, num2: T): T extends number ? number : string
function sum(num1, num2) {
  return num1 + num2
}

const res1 = sum(1, 2) // 正确
const res2 = sum('a', 'b') // 正确
const res3 = sum(1, 'a') // 错误。参数类型不一致

在条件类型中推断:

条件类型提供了 infer 关键字,可以从正在比较的类型中推断类型,然后在 true 分支里引用该推断结果。

// 如果泛型 T 是继承自函数类型,就在条件类型中推断函数的返回值并返回,否则返回 never
// R 只是一个标识符,可以任意命名
T extends (...args: any[])=>infer R ? R : never

分发联合类型:

当在泛型中使用条件类型的时候,如果传入的是一个联合类型,就会变成分发的,这个条件类型会依次应用到联合类型中的每个成员,将联合类型中的每个成员挨个执行一次。

type toArray<T> = T[]

// 此时获取到的是 (string | number)[],但实际上想要是 string[] | number[]
type numberArray = toArray<number | string>

请添加图片描述

// 此时,相当于是 toArray<string> | toArray<number>
type toArray<T> = T extends any ? T[] : never

type numberArray = toArray<number | string>

请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值