TypeScriptで、JavaScript組み込みのMapクラスやSetクラスのインスタンスの要素を後から変更できないようにし、意図しないバグを仕込んでしまうのを防ぎたい人のためのハックです。
Immutable.jsを使ってもよいのですが、名前が被っていたり、大げさだったりするので、カジュアルにset()
, delete()
, clear()
が呼び出された時に例外が飛ぶようにします。
prototypeの汚染しますが、節度を持って利用することで、コードの質を高められると信じています。
Map.extension.ts
export {};
declare global {
interface Map<K, V> {
freeze(): Map<K, V>;
}
}
const disabledOperation = (): never => {
throw new Error('disabled operation');
};
Map.prototype.freeze = function <K, V>(this: Map<K, V>): Map<K, V> {
this.set = disabledOperation;
this.delete = disabledOperation;
this.clear = disabledOperation;
return this;
};
このようなコードを用意して、使うとこんな感じになります。
const fruits = new Map<string, string>();
fruits.set('apple', '林檎');
fruits.set('orange', 'オレンジ');
fruits.freeze();
fruits.set('banana', 'バナナ'); // 例外が飛ぶ