00011-easy-tuple-to-object

Back

// readonly 对应 as const 
// T[number],把数组所有元素组成的联合类型
type TupleToObject<T extends readonly string[]> = {
  [P in T[number]]: P
}

Solution by YiShengYouNi #36976

//here PropertyKey = (string | number | symbol) 
type TupleToObject<T extends readonly PropertyKey[]> = {
  [a in T[number]]:a
}

So, T is an array that takes number as input. <T extends readonly any[]> was a problem . any[] changed to PropertyKey[].

Solution by Anonymous961 #36959

解题思路

第一步还是得看懂题目,有几个关键点需要提前了解下

首先是as const,它是一种类型断言,用于将一个表达式(如数组、对象或字面量)视为常量值,从而推导出更具体的类型,它有以下几个特点

  1. 禁止重新赋值:变量本身不能被重新赋值。
  2. 精确的类型推导:TypeScript 不会将变量的类型泛化为 string 或 number,而是直接使用字面量类型。
  3. 适用于字面量类型:主要用于数组、对象或基本类型的字面量。

在此处会将['tesla', 'model 3'] 推导为常量元组表示其不能新增、删除、修改元素(即 readonly ["tesla", "model 3", "model X", "model Y"]

然后是typeof,它作为类型查询操作符,用来获取变量的类型。

const p = {
  name: "CJ",
  age: 18,
};

type Person = typeof p;

// 等同于
type Person = {
  name: string;
  age: number;
};

了解了这两个知识点,这题的解法就呼之欲出了,其实就是遍历元组,将元组中的元素作为键,元组中的元素对应的值作为值,并返回一个对象类型

遍历元组目前还不知道怎么办,通过之前的题目,我们已经知道了如何使用 in 操作符遍历联合类型,先写一个参数为联合类型的简单版本

// PropertyKey 是 ts 内置类型:type PropertyKey = string | number | symbol
type Test<K extends PropertyKey> = {
  [P in K]: P;
};

type Case1 = Test<"a" | "b">;
// 相当于 type Case1 = { a: 'a', b: 'b' }

目前,我们的参数是联合类型,但是题目给的是元组,我们需要把元组转换成联合类型。

此处用了T[number],它可以用来获取元祖的元素类型(联合类型)。

type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P;
};

但是这样写之后,错误测试用例没有触发,还需要限制一下参数的类型

此处使用PropertyKey,它相当于type PropertyKey = string | number | symbol

题解

type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P;
};

心得与知识点

  1. as const
  2. typeof
  3. T[number]可以将获取元祖的元素类型(联合类型)
  4. PropertyKeyts的内置类型,它相当于type PropertyKey = string | number | symbol

Solution by lkwavestian #36945

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

Solution by leongaooo #36924

// your answers
type TupleToObject<T extends readonly PropertyKey[]> = {
  [K in T[number]]: K;
}

Solution by AlexBraunMagic #36919

type TupleToObject<T extends readonly any[]> = {[P in T[number]]: P}

Solution by shaishab316 #36840

type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P
}

/* _____________ Test Cases _____________ */
import type { Equal, Expect } from '@type-challenges/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], {}]>

Solution by AnastasiaSv #36760

type TupleToObject<T extends string[]> = 
{
  [K in T[number]]: K
}

Solution by Mamdouhreda #36706

type TupleToObject<T extends readonly any[]> = { [Key in T[number]]: Key }

Solution by seungdeok #36658

// type PropertyKey = string | number | symbol

// type TupleToObject<T extends readonly any[]> = {
//   [P in T[number]]: P;
// };


type TupleToObject<T extends readonly PropertyKey[]> = {
  [P in T[number]]: P
}

Solution by ChuSeongJun #36624

type TupleToObject<T extends readonly any[]> = {
    [P in keyof T]: T[P]
}

Solution by wiJeeXu #36598

// 你的答案
type TupleToObject<T extends readonly PropertyKey[]> = {
  [P in T[number]]: P
}

Solution by MrSissel #36579

// 你的答案
type TupleToObject<T extends readonly (keyof any)[]> = {
  [key in T[number]]:key
}

Solution by mola-fish #36574

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

Solution by ChemieAi #36548

// 你的答案

type TupleToObject<T extends readonly any[]> = { [K in T[number]]:K }

Solution by Rocco10086 #36535

type TupleToObject<T extends readonly any[]> = {
  [U in T[number]] : U;
}

Solution by gakki-san #36441

type TupleToObject<T extends readonly any[]> = {[P in T[number]]:P}

Solution by alirezaprime #36410

// your answers
type TupleToObject<T extends readonly PropertyKey[]> = {[J in T[number]]: J};

Solution by justBadProgrammer #36357

// 你的答案
type TupleToObject<T extends readonly any[]> = {
    [key in  T[number]]: key
}

Solution by ATravelerGo #36347

type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: P
}

Solution by 1Alex4949031 #36308

type TupleToObject<T extends readonly any[]> = { [P in T[number]]: P }

Solution by Jace254 #36265

// 你的答案
//首先要理解as const是代表的只读,(string | number | symbol)[]代表着对象的健只有这三种类型
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
  [key in T[number]]:key
}

Solution by destinyliu3 #36222

using the index property of array

type TupleToObject<T extends readonly PropertyKey[]> = {
  [p in T[number]]: p
}

Solution by lxy2222 #36201

type TupleToObject<T extends readonly any[]> = {
  [K in T[number]]: K;
}

Solution by tjd985 #36190

// your answers
type TupleToObject<T extends readonly (keyof any)[]> = {
  [key in T[number]]: key
}

Solution by goddnsgit #36181

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

Solution by asylbekduldiev #36168

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

Solution by AleksandrShcherbackov #36140

type TupleToObject<T extends readonly PropertyKey[]> = {
  [key in T[number]] : key;
}

Object 의 key 가 될 수 있는 요소들을 any 가 아닌 string | number | symbol 이기에 내장 타입인 T를 PropertyKey 로 변경

Solution by yonghyeun #36128


type TupleToObject<T extends readonly any[]> = {
  [P in T[number]]: `${P}-xyinia`
}

Solution by EvgeniyKoch #36120

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

// NOTE: PropertyKey라는 타입 alias가 있음 (`string|number|symbol`)

Solution by jhsung23 #36092