「这是我参与2022首次更文挑战的第12天,活动详情查看:2022首次更文挑战」
前言
在学习typescript的过程当中,有一个github库对其类型的学习特别有帮助,是一个有点类似于leetcode的刷题项目,能够在里面刷各种关于typescript类型的题目,本片文章带大家做其中简单难度的第三道题 11-easy-tuple-to-object
11-easy-tuple-to-object
首先我们先来阅读一下 README,题目要求我们将这个元组类型转换为对象类型,这个对象类型的键/值都是从元组中遍历出来。
在例子中的第一句话,我们就是看到了没有见过的知识点 as const,这个 as const 和 es6 中的 const 是完全不一样的:
-
const常量声明是 ES6 的语法,对 TS 而言,它只能反映该常量本身是不可被重新赋值的,它的子属性仍然可以被修改,故 TS 只会对它们做松散的类型推断 -
as const是 TS 的语法,它告诉 TS 它所断言的值以及该值的所有层级的子属性都是不可篡改的,故对每一级子属性都会做最严格的类型推断
下方也会通过 typeof 来获取这个变量的类型,我们可以对比一下各种不同变量的类型差别:
let,声明的变量可以被改变所以为 string 类型
const,声明的变量无法被改变,类型为字面量
as const,声明的变量会被加上 readonly 只读关键字
在明白了这些之后,我们就可以开始来做题了
利用js进行对比学习
我们还是先用js来模拟题目的要求。
首先函数会传入一个元组,也就是一个数组,我们需要创建一个对象,将元组中所有的属性都挂载到对象下面去,然后将这个对象返回出去。
function tupleToObject(array) {
const obj = {};
array.forEach((val) => {
obj[val] = val;
});
return obj;
}
实现TupleToObject
接着我们就按照js的逻辑来实现ts的代码
-
首先我们要遍历传入的一个只读数组,这里在上方的
as const有提到,在ts中遍历一个数组,我们需要用到 [P in T[number]] 的语法来实现一个数组的遍历 -
然后我们只需要将遍历到的属性返回
type TupleToObject<T extends readonly any[]> = {
[P in T[number]]: P;
};
这样就实现了题目的要求,但是会发现测试那边还是有地方报错:
-
报错的这一句注释的意思是,期望底下的这段代码抛出错误,否则这句注释就会报错
-
那么这里我们可以看到底下的代码会传入一个数组,但是这个数组的数据有一个数组类型和一个对象类型,这显然是不行的,在我们的对象的key中,数据类型只能有三种,分别是 number | string | symbol 这也就是这段代码为什么报错的原因,我们需要对输入的参数进行一个校验:
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[P in T[number]]: P;
};
知识点
关于上述提到了部分的知识点:
- 数组类型的遍历,在这之后,我们已经提过了 联合类型union,接口类型interface 和 数组类型 三种遍历方式
- typeof 操作符,可以用来获取一个变量或对象的类型。
- as const 语法
- @ts-expect-error 注释 今天提到了较多的新知识点 ,大家都可以去官网看看,这里底下带上 @ts-expect-error 的官方介绍,因为这个稍微比较难找
TypeScript: Documentation - TypeScript 3.9 (typescriptlang.org)
总结
以上就是今天解决的第三道题以及涉及到的ts知识点。