Type Challenges 中級編17: Fibonacci Sequence,AllCombinations, Greater Than
はじめに
GitHubのtype-challengesリポジトリは、TypeScript型システムの理解を深めるための型クイズ問題集です。今回も中級編から3つの問題に挑戦します。
今回全部難しかった、、競プロだろこんなん、
1. Fibonacci Sequence
この課題では、与えられた数 T
に対応するフィボナッチ数を返すジェネリック型 Fibonacci<T>
を実装します。フィボナッチ数列は次のように定義されます:
1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, ...
例
type Result1 = Fibonacci<3> // 2
type Result2 = Fibonacci<8> // 21
私の回答(答え見ました)
type Fibonacci<T extends number, CurrentIndex extends any[] = [1], Prev extends any[] = [], Current extends any[] = [1]> =
CurrentIndex['length'] extends T
? Current['length']
: Fibonacci<T, [...CurrentIndex, 1], Current, [...Prev, ...Current]>;
やってることは単純だけどこんな解法思いつかないよ、
解き方
-
Fibonacci
型は、フィボナッチ数列のインデックスT
を受け取り、その値を計算します。 - ジェネリックパラメータ
CurrentIndex
,Prev
,Current
を使用して再帰的に数列を計算します。 -
CurrentIndex['length']
がT
に達するまで、Current
の値を更新し続けます。
2. AllCombinations
指定された文字列に含まれる文字をそれぞれ最大で1度だけ使った文字列のすべての組み合わせの型 AllCombinations
を実装します。
例
type AllCombinations_ABC = AllCombinations<'ABC'>;
// should be '' | 'A' | 'B' | 'C' | 'AB' | 'AC' | 'BA' | 'BC' | 'CA' | 'CB' | 'ABC' | 'ACB' | 'BAC' | 'BCA' | 'CAB' | 'CBA'
私の回答
type String2Union<S extends string> =
S extends `${infer C}${infer REST}`
? C | String2Union<REST>
: never;
type AllCombinations<
STR extends string,
S extends string = String2Union<STR>
> = [S] extends [never]
? ''
: '' | {[K in S]: `${K}${AllCombinations<never, Exclude<S, K>>}`}[S];
解き方
-
String2Union
型を使用して、文字列を個々の文字のユニオン型に変換します。 -
AllCombinations
型は、再帰的に各文字の組み合わせを生成します。 - テンプレートリテラル型を用いて、各組み合わせを文字列として表現します。
これもえぐいって、、、、全然わかりませんでした。
3. Greater Than
この課題では、T > U
を判定する型 GreaterThan<T, U>
を実装します。負の数は考慮しません。
例
type Result1 = GreaterThan<2, 1> // true
type Result2 = GreaterThan<1, 1> // false
type Result3 = GreaterThan<10, 100> // false
type Result4 = GreaterThan<111, 11> // true
私の回答
type ArrayWithLength<T extends number, U extends any[] = []> =
U['length'] extends T ? U : ArrayWithLength<T, [true, ...U]>;
type GreaterThan<T extends number, U extends number> =
ArrayWithLength<U> extends [...ArrayWithLength<T>, ...infer _] ? false : true;
解き方
-
ArrayWithLength
型を使用して、指定された長さの配列を生成します。 -
GreaterThan
型は、配列の長さを比較することでT
がU
より大きいかどうかを判定します。 - 配列の展開を利用して、比較を行います。
もう今回全部難しかった、、
まとめ
これらの課題を通じて、TypeScriptの型システムに対する理解が深まり、複雑な型操作のスキルが向上します。特に、テンプレートリテラル型や再帰型、マッピング型を駆使することで、強力で柔軟な型を実装できるようになります。ぜひ、これらの課題に挑戦して、型の理解を深めてください。