09.Typescript 元组、枚举、never类型

1. 元组类型

元组就是数组的变种,它是固定数量的不同类型的元素组合。

当我们需要定义一个固定大小,不同类型值的数组时,就需要用到元组。

元组和数组的区别:

  • 元组中的元素类型可以是不同的,而且数量是固定的。
  • 数组中的元素类型需要是相同的,而且数量是不固定的。

元组的优势:如果一个方法需要返回多个值,可以把这多个值作为一个元组返回,不需要单独创建其他的类来表示。

1.1. 定义元组

ini 复制代码
// 元组类型
type MyTuple = [number, string, boolean];
const tuple: MyTuple = [1, 'hello', true]; // 正确
// const tuple2: MyTuple = [1, 'hello', true, 'world']; // 错误,元组类型的长度必须与定义的一致
// const tuple3: MyTuple = [1, 'hello']; // 错误,元组类型的长度必须与定义的一致

1.2. 当赋值或访问一个已知索引的元素时,会得到正确的类型

arduino 复制代码
// 当赋值或者访问一个已知索引的元素时,会得到正确的类型:
const firstElement: number = tuple[0]; // 正确,类型为 number
const secondElement: string = tuple[1]; // 正确,类型为 string
const thirdElement: boolean = tuple[2]; // 正确,类型为 boolean

1.3. 支持自定义名称和变为可选

typescript 复制代码
// 支持自定义名称的元组类型:
type MyTupleWithNames = [first: number, second: string, third: boolean];
const tupleWithNames: MyTupleWithNames = [1, 'hello', true]; // 正确
const firstElementWithNames: number = tupleWithNames[0]; // 正确,类型为 number

// 可选性元组类型:
type MyOptionalTuple = [number?, string?, boolean?];
const optionalTuple: MyOptionalTuple = [1, 'hello']; // 正确,可选元素可以不提供
const optionalTuple2: MyOptionalTuple = [1, 'hello', true, 'world']; // 错误,可选元素的数量不能超过定义的数量

1.4. 越界元素

当访问一个越界的元素时,TypeScript 会将其视为一个数组类型。

typescript 复制代码
// 越界元素的类型:
type MyTupleWithRest = [number, ...string[]]; // 表示第一个元素是 number,后面的元素是 string 类型的数组
const tupleWithRest: MyTupleWithRest = [1, 'hello', 'world']; // 正确,越界元素的类型是 string[]

2. 枚举类型

在 JS 中是没有枚举这个概念的,TS 帮我们定义了枚举类型,通过关键字 enum 定义。

2.1. 数字枚举

数字枚举的默认值是从 0 开始的,可以不写,默认为0.

我们也可以给枚举第一项赋值,其他成员会从我们赋值的数字开始自动增长。例如:我们给第一项赋值为1,那以此类推,第二项为2,第三项为3...。类似于数据库中的自增 id。

arduino 复制代码
// 枚举类型
// 数字枚举
enum Role {
  Reporter,
  Developer,
  Maintainer,
}

// 数组枚举的取值是从 0 开始递增的
console.log(Role.Reporter); // 0
console.log(Role.Developer); // 1
console.log(Role.Maintainer); // 2

// 增长枚举
enum Role1 {
  Reporter=1,
  Developer,
  Maintainer,
}

2.2. 字符串枚举

字符串枚举的概念很容易理解,在一个字符串枚举中,每个成员都必须用字符串字面量,或另外一个字符串枚举成员初始化。

ini 复制代码
// 字符串枚举
enum Message {
  Success = '恭喜你,成功了',
  Fail = '抱歉,失败了',
}

由于字符串枚举不能进行自增长,所以字符串枚举可以很好的进行序列化,相比于数字枚举,字符串枚举可以允许我们i提供一个运行时有意义并可读的值。独立与枚举成员的名字。这样更加能表达有用的信息。

2.3. 异构枚举

枚举可以混合字符串和数字,异构枚举就是一个即包含数字类型,又包含字符串类型的枚举。

arduino 复制代码
// 异构枚举
enum Answer {
  N,
  Y = 'Yes',
}

2.4. 常量枚举

大多数的情况下,枚举是个十分有效的方案。在某些情况下要求很严格,为了避免其他代码额外对枚举成员的访问,造成性能的额外开销。我们可以使用 const 枚举。const 枚举在编译时会被编译成常量。而普通声明的枚举会被编译成一个对象。

注意:let 和 var 都是不能声明枚举的,只能使用 const

css 复制代码
// 常量枚举 
const enum Month {
  Jan,
  Feb,
  Mar,
}
let month = [Month.Jan, Month.Feb, Month.Mar]; // 编译结果为 [0, 1, 2],而不是 ['Jan', 'Feb', 'Mar']

2.5. 接口枚举

接口枚举定义后,在使用该枚举时,声明接口要遵循该枚举的规则。

kotlin 复制代码
// 接口枚举
enum Types {
  A,
  B,
}
interface IType {
  type: Types; // 类型只能是 Types.A 或 Types.B
}

2.6. 反向映射

枚举时又反向映射属性的,当我们访问 name 时,会返回 value,访问 value 时,会返回 name。

ini 复制代码
// 反向映射
enum Enum {
  fall
}
let a = Enum.fall;
console.log(a); //0
let nameOfA = Enum[a]; 
console.log(nameOfA); //fall

2.7. 枚举成员

枚举类型可以包含多种类型的枚举成员

这里需要注意的是,数字没有 length 属性,不要去访问数字类型的 length

ini 复制代码
// 枚举成员
enum Char {
  // const
  a,
  b = Char.a,
  c = 1 + 3,
  // computed
  d = Math.random(),
  e = '123'.length,
  f = 4,
}

3. never 类型

TS 使用 never 类型表示不应该存在的状态。

never 类型是最底层类型,它是所有类型的子类型,也可以赋值给任何类型;然而,没有类型是 never 的子类型或可以赋值给never 类型(除了 never 本身之外)。即使 any 也不可以赋值给 never。

下面是几种会出现 never 类型的例子。

typescript 复制代码
// never类型
// 下面是一些使用never类型的例子:
// 1. 函数抛出错误:
function throwError(message: string): never {
    throw new Error(message);
}
// 2. 死循环:
function infiniteLoop(): never {
    while (true) { }
}
// 3. 无法到达的代码:
function unreachableCode(): never {
    return 1; // 这个函数永远不会返回
}
// 4. 类型保护中的never:
function isNumber(value: any): value is number {
    return typeof value === 'number';
}
function processValue(value: number | string): void {
    if (isNumber(value)) {
        console.log(value.toFixed(2)); // value 是 number 类型,这里可以安全调用 toFixed 方法
    } else {
        console.log(value.toUpperCase()); // value 是 string 类型,这里可以安全调用 toUpperCase 方法
    }
}
// 5. 解构中的never:
function destructuringExample(): never {
    const [x, y] = [1, 2]; // 解构数组时,x 和 y 的类型是 number
    const { a, b } = { a: 1, b: 2 }; // 解构对象时,a 和 b 的类型是 number
}
// 6. 类型断言中的never:
function assertNever(value: never): never {
    throw new Error("Unexpected object: " + value);
}

never 类型和 void 类型的区别

  1. never 类型是所有类型的子类型,而 void 类型不是。
  2. never 类型表示一个不可能存在的值,而 void 类型表示一个没有值的类型。
  3. never 类型通常用于表示函数的异常情况,而 void 类型通常用于表示函数的返回值类型。
  4. never 类型通常用于表示一个函数永远不会返回的情况,而 void 类型通常用于表示一个函数没有返回值的情况。
  5. never 类型在联合类型中会被直接移除,而 void 类型不会。

4. 代码下载

📎元组类型.ts

📎枚举类型.ts

📎never类型.ts

相关推荐
李是啥也不会3 分钟前
Vue中Axios实战指南:高效网络请求的艺术
前端·javascript·vue.js
xiaoliang7 分钟前
《DNS优化真经》
前端
一只小海獭10 分钟前
了解uno.config.ts文件的配置项---转化器
前端
贾公子13 分钟前
MySQL数据库基础 === 约束
前端·javascript
代码不行的搬运工14 分钟前
HTML快速入门-4:HTML <meta> 标签属性详解
java·前端·html
Chrome深度玩家21 分钟前
如何下载Google Chrome适用于AI语音交互的特制版
前端·人工智能·chrome
JavaDog程序狗25 分钟前
【实操】uniapp纯前端搞个识别植物花草小程序
前端·vue.js·uni-app
贾公子26 分钟前
element ui & plus 版本 日期时间选择器的差异
前端·javascript
贾公子31 分钟前
form组件的封装(element ui ) 简单版本
前端·javascript
贾公子32 分钟前
下拉框组件的封装(element ui )
前端·javascript