【type-challenges】元祖转换为对象
元祖转换为对象
首先熟悉下 as const 的用法,在这里会将数组变成只读元祖
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const // 等同于 tuple 定义为 readonly ["tesla", "model 3", "model X", "model Y"]
其次可以用 T[number] 拿到元祖的联合类型:
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
type keys = (typeof tuple)[number] // "tesla" | "model 3" | "model X" | "model Y"
剩下的就比较简单了:
type TupleToObject<T extends readonly any[]> = {
[key in T[number]]: key
}
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
type result = TupleToObject<typeof tuple>
但是还有个问题,题面上希望以下代码能抛错:
type error = TupleToObject<[[1, 2], {}]>
显然目前用 any 是不会抛错的,而 js 中对象的 key 只能是 string、number 或者 symbol 类型,所以可以进一步约束下:
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[key in T[number]]: key
}
而 ts 中 PropertyKey 就是 string | number | symbol:
type TupleToObject<T extends readonly PropertyKey[]> = {
[key in T[number]]: key
}
另外一个比较有趣的技巧是 keyof any 也同样可以获取以上结果:
type ObjectKeys = keyof any // string | number | symbol
浙公网安备 33010602011771号