問題 & 解答
option(key, value)
を任意の数チェインして、最終的な結果をget()
で呼び出すような 2 つの関数を提供する型を定義する。
type Chainable<Options = {}> = { option<K extends string, V>( key: K, value: V ): Chainable<Options & { [S in K]: V }>; get(): Options;};
全然わからなくて答えをみたので、解析していく。まず、単純にoption
メソッドを持つオブジェクトを考える。
このメソッドの要件は
- 引数は
key
とvalue
で、key
にstring
、value
に任意の型を受ける - 戻り値はここまで追加された option(オブジェクト)と、今回メソッドに渡された key と value で生成された option(オブジェクト)が合わさったもの。
// ここまでに定義されたOptionをチェーンする。何もOptionがなければ`{}`が初期値として設定されるtype Chainable<Options = {}> = { option<K extends string, V>( key: K, value: V ): Chainable<Options & { [S in K]: V }>;};
declare const base: Chainable; // Chainable<{}>
// Optionsは初期値`{}`// Chainable<{} & { "require": boolean }>// Chainable<{ require: boolean }>const requireOptionAdded = base.option("require", false);
// optionで返されているOptionsは`{ require: boolean }`// Chainable<{ require: boolean } & { old: boolean }>// Chainable<{ require: boolean, old: boolean; }>const oldOptionAdded = requireOptionAdded.option("old", true);
あとは現在保持している Options を返すようにget
を実装する。
type Chainable<Options = {}> = { option<K extends string, V>(key: K, value: V): Chainable<Options & { [S in K]: V }> get(): Options;}
調べたこと
declare
)
アンビエント宣言(JavaScript コードを生成せずに、型推論のためだけの情報を渡すのに使用する。
declare;a: number;
感想
再帰とはまた違った形式だけれど、地味に汎用性の高い型定義だと思うので覚えておこう