[TypeScript] Type Challenges #11 - Tuple to Object

86 阅读1分钟

题目描述

将一个元组类型转换为对象类型,这个对象类型的键/值和元组中的元素对应。

例如:

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 { EqualExpect } from './test-utils'

const tuple = ['tesla''model 3''model X''model Y'as const
const tupleNumber = [1234as 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>, { 11223344 }>>,
  Expect<Equal<TupleToObject<typeof tupleSymbol>, { [sym1]: typeof sym1;[sym2]: typeof sym2 }>>,
  Expect<Equal<TupleToObject<typeof tupleMix>, { 11'2''2'33'4''4';[sym1]: typeof sym1 }>>,
]

// @ts-expect-error
type error = TupleToObject<[[12], {}]>


// ============= 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