配列から配列への型レベルmap
配列を取って、計算して、配列を返す型
hsのような言語で考えるなら、再帰関数を想像するがぜんぜん異なるmrsekut.icon
TSの難しいポイントの1つだと思う
イディオムとして頭に入っていないと使えない
[a,b,c]→[f a, f b, f c]と変換する
機能的には、Mapped Tuple Typeを使用している
こんなふうに書く
code:ts
type Hoge<XS extends unknown[]> = {
K in keyof XS: F<XSK>;
};
Fは何かしらの、適用したい型関数
この[P in keyof T]: ..というイディオムは、recordに対して使われているのはよく見るmrsekut.icon
例えば、PartialとかRequiredとかReadonlyとか
これを配列に使う
例
numberの配列を、stringの配列に変換する
code:ts
type Nums2Strs<T extends number[]> = {
K in keyof T: Num2Str<TK>;
};
// 関数
type Num2Str<N> = N extends number ? ${N} : never;
// 結果
type Hoge = Nums2Strs<1, 2, 3, 4>; // '1', '2', '3', '4'
例
Promise.all()の型付け
型関数の重ね具合に依って、普通に書くとerrorになるケースが存在する
code:ts
type Box<V = unknown> = { value: V };
type Unbox<B extends Box> = B'value';
type UnboxAll<T extends Box[]> = {
// I in keyof T: Unbox<TI>; // こう書きたいが書けない
I in keyof T: Unbox<Extract<TI, Tnumber>>; // しゃーなし、こう書く
};
type B = Box<'a'>, Box<'b'>, Box<'c'>;
type C = UnboxAll<B>; // 'a', 'b','c'
https://github.com/microsoft/TypeScript/issues/27995#issuecomment-575006947
ちなみに、Map<F, XS>のような高階型関数は定義できない
高階多相型がないので
型引数Fは、何かしらの型関数であって欲しいが、それが定義できない
頑張る方法はあるっぽい
ref TypeScriptで高階多相型
#配列型周りのイディオム