0
0

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 型は、配列の長さを比較することで TU より大きいかどうかを判定します。
  • 配列の展開を利用して、比較を行います。

もう今回全部難しかった、、

まとめ

これらの課題を通じて、TypeScriptの型システムに対する理解が深まり、複雑な型操作のスキルが向上します。特に、テンプレートリテラル型や再帰型、マッピング型を駆使することで、強力で柔軟な型を実装できるようになります。ぜひ、これらの課題に挑戦して、型の理解を深めてください。

参考記事

0
0
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0