// 你的答案
## ✅ 正确实现
```ts
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[P in T[number]]: P
}
T extends readonly (string | number | symbol)[]
为什么需要这个约束?
string | number | symbol
类型readonly
确保处理的是字面量类型T[number]
获取元素值的联合类型// 对于 tuple = ['tesla', 'model 3'] as const
type Elements = T[number] // "tesla" | "model 3"
T[number]
是索引访问类型,它获取数组中所有元素的联合类型。
[P in T[number]]: P
//这相当于:
// 遍历联合类型 "tesla" | "model 3"
{
tesla: "tesla";
"model 3": "model 3";
}
完整正确代码
/* _____________ 你的代码 _____________ */
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[P in T[number]]: P
}
keyof T
- 获取键的集合T
的所有属性名Object.keys()
的类型版本T[number]
- 获取值的集合T
的所有元素值类型map()
操作的类型版本// 使用 keyof - 基于属性名创建新类型
type Getters<T> = {
[K in keyof T]: () => T[K]
}
interface User {
name: string;
age: number;
}
type UserGetters = Getters<User>;
// { name: () => string; age: () => number }
// 使用 T[number] - 基于元素值创建新类型
type TupleToObject<T extends readonly PropertyKey[]> = {
[P in T[number]]: P
}
const colors = ['red', 'green', 'blue'] as const;
type ColorMap = TupleToObject<typeof colors>;
// { red: "red"; green: "green"; blue: "blue" }
keyof
→ 想到 Keys(钥匙/键)→ 获取键名
T[number]
→ 想到数组索引访问 → 获取值类型
Solution by nyk233233 #37430
type TupleToObject<T extends readonly any[]> = {
[I in T[number]] : I
}
T extends readonly any[]
T
must be a tuple (or readonly array).
Example:
const tuple = ['a', 'b', 'c'] as const;
type T = typeof tuple;
// readonly ["a", "b", "c"]
T[number]
In TypeScript, indexing a tuple/array type with number
gives you the union of all its element types.
Example:
type Elements = ["a", "b", "c"][number];
// "a" | "b" | "c"
So if T = readonly ["a", "b", "c"]
, then T[number] = "a" | "b" | "c"
.
[I in T[number]]
I
in the union "a" | "b" | "c"
, create a property whose key is I
.: I
I
itself."a"
maps to "a"
, "b"
maps to "b"
, etc.If you pass in:
const tuple = ["a", "b", "c"] as const;
type Result = TupleToObject<typeof tuple>;
Then:
type Result = {
a: "a";
b: "b";
c: "c";
}
✅ In plain English: My type takes a tuple of literal values and produces an object type where each element of the tuple becomes both a key and its corresponding value.
Solution by 3aluw #37421
type TupleToObject<T extends readonly any[]> = {
[D in T[number]]: D;
}
Solution by minseonkkim #37346
type TupleToObject<T extends readonly any[]> = {
[P in T[number]]: P;
};
Solution by Nakamura25257 #37256
type TupleToObject<T extends readonly PropertyKey[]> = {
[P in T[number]]: P;
};
type TupleToObject<T extends readonly (keyof any)[]> = {
[P in T[number]]: P;
};
type TupleToObject<T extends readonly (string|symbol|number)[]> = {
[P in T[number]]: P;
};
三种写法
T
是一个元组类型,T[number]
表示元组中所有项的 |
联合类型key
,要对元素项做类型限制keyof any
可以得到对象 key 所有可取的类型 (string|number|symbol)
Solution by djdidi #37118
type TupleToObject<T extends readonly (string | number | symbol)[]> = {
[P in T[number]]:P
}
Solution by 359Steve #37012
type TupleToObject<T extends readonly any[]> = {
[P in T[number]]: P;
}
Solution by mag123c #36993
// 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
,它是一种类型断言,用于将一个表达式(如数组、对象或字面量)视为常量值,从而推导出更具体的类型,它有以下几个特点
在此处会将['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;
};
心得与知识点
as const
typeof
T[number]
可以将获取元祖的元素类型(联合类型)PropertyKey
是ts
的内置类型,它相当于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