Type Challenges 中級編16: BEM style string, InorderTraversal, Flip
はじめに
GitHubのtype-challengesリポジトリは、TypeScript型システムの理解を深めるための型クイズ問題集です。高品質な型を作成することで、バグを減らし、プロジェクトの保守性を向上させることができます。今回も中級編から3つの問題に挑戦します。
1. BEM style string
この課題では、BEM(Block, Element, Modifier)スタイルの文字列を生成する型を実装します。BEMはCSSのクラス命名規則で、ブロック、要素、修飾子によってクラス名を構成します。
筆者はフロントエンドにめっぽう弱いのでBENをこの問題で知りました。笑
私の回答
type BEM<B extends string, E extends string[], M extends string[]> =
`${B}${E extends [] ? '' : `__${E[number]}`}${M extends [] ? '' : `--${M[number]}`}`;
解き方
-
BEM
型は、ブロックB
、要素E
、修飾子M
を受け取り、テンプレートリテラル型を用いて文字列を生成します。 - 要素
E
が空配列でない場合は__
を、修飾子M
が空配列でない場合は--
を追加します。 -
${E[number]}
と${M[number]}
により、配列のすべての要素に対応する文字列を生成します。
2. InorderTraversal
この課題では、二分木の中順(inorder)走査を行う型を実装します。
これ全然わからなかった、、
例
const tree1 = {
val: 1,
left: null,
right: {
val: 2,
left: {
val: 3,
left: null,
right: null,
},
right: null,
},
} as const;
type A = InorderTraversal<typeof tree1>; // [1, 3, 2]
私の回答
type TreeNode = {
val: number;
left: TreeNode | null;
right: TreeNode | null;
};
type InorderTraversal<T extends TreeNode | null> =
T extends TreeNode ?
[...InorderTraversal<T['left']>, T['val'], ...InorderTraversal<T['right']>]
: [];
解き方
-
InorderTraversal
型は、二分木T
を受け取り、再帰的に左部分木、中間ノード、右部分木を走査して値を収集します。 - 再帰的に各部分木を走査し、結果を結合します。
このようにして、二分木の中順走査を行う型を実装することができます。
競プロやんけ。。。
3. Flip
この課題では、オブジェクトのキーと値を反転させる型を実装します。
例
type FlipExample1 = Flip<{ a: "x", b: "y", c: "z" }>; // {x: 'a', y: 'b', z: 'c'}
type FlipExample2 = Flip<{ a: 1, b: 2, c: 3 }>; // {1: 'a', 2: 'b', 3: 'c'}
type FlipExample3 = Flip<{ a: false, b: true }>; // {false: 'a', true: 'b'}
私の回答
type Flip<T> = {
[K in keyof T as `${T[K]}`]: K;
};
解き方
-
Flip
型は、オブジェクトT
を受け取り、キーと値を反転させた新しいオブジェクトを返します。 - テンプレートリテラル型を用いて、値をキーとして使用します。
このようにして、オブジェクトのキーと値を反転させる型を実装することができます。
as さえ分かれば問題なし!
まとめ
これらの課題を通じて、TypeScriptの型システムに対する理解が深まり、複雑な型操作のスキルが向上します。特に、テンプレートリテラル型や再帰型、マッピング型を駆使することで、強力で柔軟な型を実装できるようになります。ぜひ、これらの課題に挑戦して、型の理解を深めてください。