項目47 モンキーパッチではなく、より型安全なアプローチを採用する
JavaScriptの特徴として、オブジェクトやクラスがオープンで、任意のプロパティを追加できる点
code:ts
window.monkey = 'Tamarin';
document.monkey = 'Howler';
組み込みオブジェクトにプロパティを追加することをモンキーパッチという
モンキーパッチは、グローバルに値を管理することになるため、良い設計ではない
プログラム間に良きせぬ依存関係を生むきっかけになるため
モンキーパッチはTypeScriptにおいても問題を生む
モンキーパッチしたプロパティの型を型チェッカーが認識できない点
code:ts
document.monkey = 'Tamarin';
// ~~~~~~ Property 'monkey' does not exist on type 'Document'
// プロパティ 'monkey' は型 'Document' に存在しません。
解決手段としてanyアサーションがあるが、良い手段ではない
code:ts
(document as any).monkey = 'Tamarin'; // OK
最善の解決手段は、window、document、DOMにモンキーパッチをしないこと
上記が難しい場合は、オーグメンテーションを使う
Windonwの型を拡張し、任意のプロパティがあることを伝える
code:ts
declare global {
interface Window {
/** 現在ログインしているユーザー */
user: User;
}
}
ただ、問題点もある
グローバル値がいつ格納されるかわからないのでundefinedの状態を考慮する必要がある
code:ts
declare global {
interface Window {
/** 現在ログインしているユーザー */
user: User | undefined;
}
}
// ...
export function greetUser() {
alert(Hello ${window.user.name}!);
// ~~~~~~~~~~~ 'window.user' is possibly 'undefined'.
// 'window.user' は 'undefined' の可能性があります。
}
#TypeScript