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をチェーンする。何も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;
再帰とはまた違った形式だけれど、地味に汎用性の高い型定義だと思うので覚えておこう