传入一个元组类型,将这个元组类型 转换为 对象类型,这个对象类型的键/值 都是 从元组中 遍历出来的。
例如:
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
type result = TupleToObject<typeof tuple>
expected {
tesla: 'tesla',
'model 3': 'model 3',
'model X': 'model X',
'model Y': 'model Y'
}
先用js的思路写一遍
const arr = ['tesla', 'model 3', 'model X', 'model Y']
const obj = {}
for (let k of arr) {
obj[k] = k
}
console.log(obj)
知识点:
1、as const : const 断言,作用是使其所有东西变成只读。
比如说const tuple = ['tesla', 'model 3', 'model X', 'model Y'] 变成const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const 就变成 const tuple: readonly ["tesla", "model 3", "model X", "model Y"]
2、ts遍历数组写法 : 【in T[number]】
3、typeof 的作用 : 将js中的let const var变量转换成ts的type interface
4、例子中type error = TupleToObject<[[1, 2], {}]>为什么没有typeof关键字?这里的[[1, 2], {}]指的是类型t(写死的类型),而不是js里的值
解答:
type TupleToObject<T extends any[]> = {
[k in T[number]]: k
}
1、这里为啥加readonly 类型“readonly ["tesla", "model 3", "model X", "model Y"]”不满足约束“any[]”。 类型 "readonly ["tesla", "model 3", "model X", "model Y"]" 为 "readonly",不能分配给可变类型 "any[]"。
因为const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const也就是typeof tuple>是readonly, 后边的{ tesla: 'tesla'; 'model 3': 'model 3'; 'model X': 'model X'; 'model Y': 'model Y' }这个是写死的也是readonly,
所以 type TupleToObject<>这里面的饿 T extends any[] 也要加上个readonly 才行。
接着就是ts中数组的循环 [k in T[number]]
至此,这道题就完成了。
但是,当我要提交答案的时候,发现有个地方报了错,标注了红色波浪线:
// @ts-expect-error 这个注释的作用是:这个注释用来指示下一行代码预期应该包含错误,下一行代码的错误将不会被编译器报告。这在对类型进行预期失败的测试时很有用
解释一下为什么报错:
ts-expect-error 这个注释,需要我们去修改 TupleToObject的泛型限制,才不会出现错误提示。作为对象的key只能是number string 以及 symbol类型,所以,我们需要将原来的any[] 修改为 {number | string | symbol[]}
最终解答:
type TupleToObject<T extends (number | string | symbol)[]> = {
[k in T[number]]: k
}