TypeScript でモジュール内でのみ参照可能なグローバル変数を宣言する ― 2021年03月21日 15時34分
Web ブラウザで使われる JavaScript ライブラリの中には、グローバル変数 (window
オブジェクトのプロパティ) をはやすものがあります。Google Tag Manager の window.dataLayer
や、Canva ボタンの window.Canva
などです。
そうしたグローバル変数をあちこちのモジュールから直接操作していると保守性が下がってしまうので、ラッパーとなるモジュールを用意したいところです。グローバル変数を直接操作するのはラッパーモジュール内のみにとどめ、他のモジュールはラッパーモジュールを介して外部ライブラリにアクセスするという仕組みです。
このとき、ラッパーモジュール内でグローバル変数にアクセスしつつ、他のモジュールではそのグローバル変数にアクセスできないようにするには、どうしたらよいでしょうか。
TypeScript でのグローバル変数の宣言は以下のように declare global
を使うのが基本ですが、これだと他のモジュールでも window.dataLayer
にアクセスできてしまいます。
declare global {
interface Window {
dataLayer: object[];
}
}
ラッパーモジュール内で以下のように window
変数を宣言しなおすことで、グローバル変数を参照できる範囲がラッパーモジュール内に限定されます。(「グローバル変数」といいつつ、window
オブジェクトのプロパティとしてアクセスすることになりますが。)
declare const window: Window['window'] & {
dataLayer: object[];
};
// このモジュール内では `window.dataLayer.push(...)` と書ける。
Window['window']
はもともとの window
オブジェクトの型を指します。それとの交差型 (intersection types) を取ることで、window
オブジェクトの既存のプロパティ (window.setTimeout
など) にも、新たに宣言したプロパティにもアクセスできます。
最近のコメント