問題
タプルを受け取り、その各値のkey/valueを持つオブジェクトの型に変換する型を実装します。
例えば:
```ts
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'}
```
与えられた配列の各要素をkey。valueにmapしたオブジェクト型を作成してくださいという問題です。
回答
type TupleToObject<T extends readonly any[]> = {
[key in T[number]]: key
}
T[number]
がUnionで返されることを知っていれば簡単に解くことができます。
ちょっと解説
T[number]
配列T各要素のUnion型を取得できます。
なぜこれでUnion型がとれるかというと、単純なタプル型とは以下のような型を持つのと同義であり、
interface StringNumberPair {
// specialized properties
length: 2;
0: string;
1: number;
// Other 'Array<string | number>' members...
slice(start?: number, end?: number): Array<string | number>;
}
この型に対してnumber型でインデックスされた値をとりだすからですね。
['tesla', 'model 3', 'model X', 'model Y']
の場合、
interface XXX {
length: 4;
0: "tesla";
1: "model 3";
2: "model X";
3: "model Y";
}
のような型をもつものとみなされ、number型でインデックスされている四つがUnionとして取り出されるわけですね。
ちなみに、以下のように数字を指定すればしっかりその数字に対応した値が返ってきます。
type A = typeof tuple;
type B = A[1] // type B = "model 3"
また、lengthの取得も可能です。
type A = typeof tuple;
type B = A["length"] // type B = 4