元组转换为对象

126 阅读2分钟

题目解析

给定一个元组类型,将其转换为对象类型,其中元组的每个元素作为对象的键和值。

示例分析

假设我们有一个元组const tuple = ['a', 'b', 'c'],我们希望将其转换为如下的对象类型

{
    a: 'a',
    b: 'b',
    c: 'c'
}

题解


type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [P in T[number]]: P;
};

const tuple = ['a', 'b', 'c'] as const;

type TupleObject = TupleToObject<typeof tuple>;

const obj: TupleObject = {
  a: 'a',
  b: 'b',
  c: 'c'
};

// 下面的代码会报错,因为 'd' 不在元组中
// const invalidObj: TupleObject = {
//     d: 'd'
// };
  • type TupleToObject<T>:定义一个泛型类型 TupleToObject,它接受一个类型参数 T
  • T extends readonly (string | number | symbol)[]:约束 T 必须是一个只读的数组,数组元素类型为 stringnumbersymbol
  • [P in T[number]]:这是一个映射类型,用于遍历 T 中的每个元素。
    • T[number]:获取元组 T 中所有元素的联合类型。例如,如果 T['a', 'b', 'c'],那么 T[number] 的类型是 'a' | 'b' | 'c'
  • { [P in T[number]]: P; }:将每个元素 P 作为对象的键和值。

知识点

as const的作用

  1. 将数组或对象的元素或属性设置为只读属性:使用as const后,数组或对象的元素或属性变为只读,不能被修改。
  2. 将类型断言为更精准的字面量类型:使用as const后,数组或对象的类型将变为具体的字面量类型,而不是更宽泛的类型。

使用示例

  1. 在对象中使用as const:假如我们有一个对象person,我们希望将其属性设为只读,并且类型为具体的字面量类型。

    const person = {
      name: "Alice",
      age: 30
    } as const;
    
    // 下面的代码会报错,因为属性是只读的
    // person.name = "Bob";
    // person.age = 31;
    

    as const将对象的所有属性设置为只读,并将其类型设置为具体的字面量类型,person的类型变为:

    type SettingPerson = typeof person;
    
    // 此时的 SettingPerson 的类型就是
    // {
    //     readonly name: "Alice";
    //     readonly age: 30;
    // }
    
  2. 在数组中使用as const,假设我们有一个数组colors,我们希望将其元素设为只读,并且类型为具体的字面量类型。

    const colors = ['red', 'green', 'blue'] as const;
    
    // 下面的代码会报错,因为数组元素是只读的
    // colors[0] = 'yellow';
    

    as const将数组中所有元素设置为只读,并将其设为具体的字面量类型。colors的类型变为:

    readonly ['red', 'green', 'blue']