type-challenges 3日目: 11-Tuple to Object

問題 & 解答

type-challenges/README.md at main · type-challenges/type-challenges

タプルを受け取り、その各値のkey/valueを持つオブジェクトの型に変換する型を実装する

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'}

文字列型の配列を受け取り、各要素をキーと値に持つオブジェクトとしてマッピングする。

type TupleToObject<T extends readonly string[]> = { [P in T[number]]: P }
// このテストケース特有なら以下の方がいいかもしれない
type TupleToObject<T extends readonly [string, string, string, string]> = { [P in T[number]]: P }

調べたこと

Tuple型

let a: [number] = [1]
let b: [string, string, number] = ['ikuma', 'takuma', 2]

参考:O’Reilly Japan - プログラミングTypeScript

const assertion

参考:constアサーション「as const」 (const assertion) | TypeScript入門『サバイバルTypeScript』

インデックスシグネチャ

配列の要素の型を取得する

readonlyな配列

いくつかの定義方法がある

// readonly T[]
const names: readonly string[] = ['akuma', 'bkuma', 'ckuma']
// ReadonlyT[]>
const names: Readonly<string[]> = ['akuma', 'bkuma', 'ckuma']
// ReadonlyArray<T>
const names: ReadonlyArray<string> = ['akuma', 'bkuma', 'ckuma']

タプルの場合は次のように定義する

// readonly
const names: readonly [number, string] = ['akuma', 'bkuma', 'ckuma']
// Readonly
const names: Readonly<[number, string]> = ['akuma', 'bkuma', 'ckuma']

感想

解いた後に回答をみたら、any[]で受け取っている人もいたり、string[]で受け取っている人もいたり、何がいいんだろうと思いました。自分はもともと「タプルなんだから、[string, string, string, string]で受け取るだろう」と思ってやっていたのですが、そういう感じでもないんですかね。