TypeScript 类型体操之 Readonly & Tuple to Object

今天继续学 TypeScript 类型体操。按难度来的,学习下第7题 Readonly 和第11题 Tuple to Object

7、Readonly

Readonly 的使用

Readonly 是 Typescript 提供的内置工具类型,Readonly<T>,用于将类型 T 中的所有属性设置为只读。

举个例子,如何使用 Readonly<T> 工具类型:

typescript 复制代码
interface Person {
  name: string;
  age: number;
}

const person: Readonly<Person> = {
  name: 'Alice',
  age: 25,
};

person.name = 'Bob'; // 编译错误,无法修改只读属性

console.log(person); // 输出: { name: 'Alice', age: 25 }

在上述示例中,我们使用 Readonly<Person> 工具类型将 Person 类型中的所有属性设置为只读。然后,我们创建了一个 person 对象,并尝试修改其 name 属性,但由于 person 是只读类型,所以会在编译时报错。

通过使用 Readonly<T> 工具类型,我们可以方便地将任何类型的属性设置为只读,提高代码的可靠性和安全性。

Readonly 的实现

1、首先在 TypeScript 中,可以使用 readonly 修饰符来指定一个只读属性。

typescript 复制代码
interface Person {
  readonly name: string;
  age: number;
}

const person: Person = {
  name: 'Alice',
  age: 25,
};

person.name = 'Bob'; // 编译错误,无法修改只读属性

console.log(person); // 输出: { name: 'Alice', age: 25 }

通过使用 readonly 修饰符,我们可以指定某个属性为只读,防止其被修改。

2、然后在 TypeScript 类型体操之 Pick 中我们已经学到了关键字 inkeyof

在映射类型中,in 关键字用于遍历一个类型的属性名,并对每个属性进行相应的操作。
keyof 是 TypeScript 中的一个关键字,用于获取一个类型的所有属性名组成的联合类型。

现在可以很简单的实现 Readonly 了。

ts 复制代码
type MyReadonly<T> = {
  readonly [key in keyof T]: T[key]
}

11、Tuple to Object

这个个人认为是相对有点难度的题目。之前面试的时候被问到过,当时真的是一脸懵逼。T^T 然后就挂了。

传入一个元组类型,将这个元组类型转换为对象类型,这个对象类型的键/值都是从元组中遍历出来。

例如:

ts 复制代码
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const

type result = TupleToObject<typeof tuple> 
// { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}

1、什么是元组类型

元组类型是 TypeScript 中的一种特殊数据类型,它允许我们定义一个固定长度和固定类型顺序的数组。

在元组类型中,每个元素的类型可以是不同的。我们可以通过使用方括号 [] 来定义一个元组类型,并在方括号中指定每个元素的类型。

以下是一个示例代码,展示了如何定义和使用元组类型:

typescript 复制代码
let tuple: [string, number, boolean];

tuple = ['apple', 10, true]; // 合法赋值

tuple = [10, 'apple', true]; // 错误,元素类型不匹配

let name: string = tuple[0]; // 类型为 string
let age: number = tuple[1]; // 类型为 number
let isValid: boolean = tuple[2]; // 类型为 boolean

在上述示例中,我们定义了一个名为 tuple 的元组类型,其中包含三个元素,分别是 stringnumberboolean 类型。然后,我们可以将符合元组类型定义的值赋给 tuple 变量。

注意,元组类型要求每个元素的类型和顺序都要与定义一致。如果赋值时不符合元组类型的定义,TypeScript 编译器会报错。

2、获取元组类型中所有元素的联合类型

我们可以通过 T[number] 表示元组类型 T 中的所有元素的联合类型。因为下标是 number 类型,而通过下标我们可以获取所有的元组元素,所以 T[number] 就可以获取所有的元素了。代码举例:

typescript 复制代码
type Tuple = [string, number, boolean];

type TupleElements = Tuple[number]; // 类型为 string | number | boolean

3、通过 in 来遍历联合类型

前面提到了

在映射类型中,in 关键字用于遍历一个类型的属性名,并对每个属性进行相应的操作。

我们通过 in 来遍历映射类型的属性时,需要遍历所有属性名组成的联合类型。

在之前获取映射类型的属性名组成的联合类型时,我们可以通过 keyof 获取,而对于元组类型,我们直接通过 T[number] 获取。

所以现在可以写出答案:

ts 复制代码
type TupleToObject<T extends readonly any[]> = {
  [key in T[number]]: key
}

但这个时候还是会报错,原因是对象的键只可能使 stringnumbersymbol 这三种类型,而 any 却超出了这个范围,所以简单修改一下即可。

ts 复制代码
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [key in T[number]]: key
}

为什么要加 readonly

题目给定的代码中加了 readonly ,在这里加不加有什么区别呢?

ts 复制代码
type TupleToObject<T extends (string | number | symbol)[]> = {
  [key in T[number]]: key
}
const tuple = [1, '2', 3, '4']
type ObjectByTuple = TupleToObject<typeof tuple>
// type ObjectByTuple = {
//   [x: string]: string;
//   [x: number]: number;
// }

如果这里我们原始对象为非 const 的时候,我们可以看到得到的映射类型是下标类型对应值类型,但是和元组中具体的值无关。

而当我们尝试指定 const 和相对应的 readonly

ts 复制代码
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [key in T[number]]: key
}
const tuple = [1, '2', 3, '4'] as const
type ObjectByTuple = TupleToObject<typeof tuple>
// type ObjectByTuple = {
//     1: 1;
//     2: "2";
//     3: 3;
//     4: "4";
// }

我们可以看到,得到的映射类型是下标对应相对的值。

对比题目要求,可以知道我们需要的是下面这个解法。

相关推荐
_.Switch41 分钟前
Python Web 应用中的 API 网关集成与优化
开发语言·前端·后端·python·架构·log4j
一路向前的月光1 小时前
Vue2中的监听和计算属性的区别
前端·javascript·vue.js
长路 ㅤ   1 小时前
vite学习教程06、vite.config.js配置
前端·vite配置·端口设置·本地开发
长路 ㅤ   1 小时前
vue-live2d看板娘集成方案设计使用教程
前端·javascript·vue.js·live2d
Fan_web1 小时前
jQuery——事件委托
开发语言·前端·javascript·css·jquery
安冬的码畜日常1 小时前
【CSS in Depth 2 精译_044】第七章 响应式设计概述
前端·css·css3·html5·响应式设计·响应式
莹雨潇潇2 小时前
Docker 快速入门(Ubuntu版)
java·前端·docker·容器
Jiaberrr2 小时前
Element UI教程:如何将Radio单选框的圆框改为方框
前端·javascript·vue.js·ui·elementui
Tiffany_Ho3 小时前
【TypeScript】知识点梳理(三)
前端·typescript
安冬的码畜日常4 小时前
【D3.js in Action 3 精译_029】3.5 给 D3 条形图加注图表标签(上)
开发语言·前端·javascript·信息可视化·数据可视化·d3.js