generated at
配列から配列への型レベルmap
配列を取って、計算して、配列を返す型
hsのような言語で考えるなら、再帰関数を想像するがぜんぜん異なるmrsekut
TSの難しいポイントの1つだと思う
イディオムとして頭に入っていないと使えない
[a,b,c] [f a, f b, f c] と変換する
機能的には、Mapped Tuple Typeを使用している


こんなふうに書く
ts
type Hoge<XS extends unknown[]> = { [K in keyof XS]: F<XS[K]>; };
F は何かしらの、適用したい型関数
この [P in keyof T]: .. というイディオムは、recordに対して使われているのはよく見るmrsekut
例えば、 Partial とか Required とか Readonly とか
これを配列に使う



number の配列を、 string の配列に変換する
ts
type Nums2Strs<T extends number[]> = { [K in keyof T]: Num2Str<T[K]>; }; // 関数 type Num2Str<N> = N extends number ? `${N}` : never; // 結果 type Hoge = Nums2Strs<[1, 2, 3, 4]>; // ['1', '2', '3', '4']





型関数の重ね具合に依って、普通に書くとerrorになるケースが存在する
ts
type Box<V = unknown> = { value: V }; type Unbox<B extends Box> = B['value']; type UnboxAll<T extends Box[]> = { // [I in keyof T]: Unbox<T[I]>; // こう書きたいが書けない [I in keyof T]: Unbox<Extract<T[I], T[number]>>; // しゃーなし、こう書く }; type B = [Box<'a'>, Box<'b'>, Box<'c'>]; type C = UnboxAll<B>; // ['a', 'b','c']



ちなみに、 Map<F, XS> のような高階型関数は定義できない
高階多相型がないので
型引数 F は、何かしらの型関数であって欲しいが、それが定義できない
頑張る方法はあるっぽい