题目描述
将一个元组类型转换为对象类型,这个对象类型的键/值和元组中的元素对应。
例如:
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'}
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
const tupleNumber = [1, 2, 3, 4] as const
const sym1 = Symbol(1)
const sym2 = Symbol(2)
const tupleSymbol = [sym1, sym2] as const
const tupleMix = [1, '2', 3, '4', sym1] as const
type cases = [
Expect<Equal<TupleToObject<typeof tuple>, { tesla: 'tesla'; 'model 3': 'model 3'; 'model X': 'model X'; 'model Y': 'model Y' }>>,
Expect<Equal<TupleToObject<typeof tupleNumber>, { 1: 1; 2: 2; 3: 3; 4: 4 }>>,
Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1;[sym2]: typeof sym2 }>>,
Expect<Equal<TupleToObject<typeof tupleMix>, { 1: 1; '2': '2'; 3: 3; '4': '4';[sym1]: typeof sym1 }>>,
]
// @ts-expect-error
type error = TupleToObject<[[1, 2], {}]>
// ============= Your Code Here =============
type TupleToObject<T extends readonly PropertyKey[]> = {
[P in T[number]]: P
}
1、PropertyKey 是 TypeScript 的内置类型,它本质上就是string | number | symbol这种联合类型
通过T extends readonly PropertyKey[]这样的约束,来确保传入的元组T里面的每个元素都是合法的对象键的类型
type PropertyKey = string | number | symbol
2、T[number]的作用是获取元组T中所有元素的类型集合
例如,当T是['tesla', 'model 3', 'model X', 'model Y'] as const这个元组类型时,T[number]实际获取到的就是'tesla'、'model 3'、'model X'、'model Y'这些元素的类型
然后通过[P in T[number]]: P这样的映射类型语法,把从T[number]中获取到的每个元素类型P,映射为对象的键,并且把这个键的属性值类型也设置为P