TypeScriptでのイベント名をclickで指定するのはもう辞めようという記事を読んで。ActionScriptでも同様な管理を公式が用意してくれていたのでとても便利だったのを思い出しました。ところがTypeScriptはあんまり公式でこういったものを用意してくれません。こういったコードの安全性やメンテナンス製に関わる箇所は公式が運用を広めるべきなんですが…。
namespace + const
さて、TypeScriptでは上記の方法以外にもいい方法があります。それはnamespace
とconst
を使う方法です。
/**
* イベント名を列挙したネームスペース
*/
export namespace EventName{
export const LOAD = "load";
export const CLICK = "click";
export const MOUSE_MOVE = "mousemove";
}
window.addEventListener(EventName.LOAD, ()=>{alert("ウィンドウのロードが完了しました。")});
EnumClass1をつかった方法に比べると以下の利点があります。
-
const
で宣言できるので再代入がコンパイルエラーになる
- EnumClassでスタティックプロパティとして定義した場合、再代入してもTypeScriptのチェックをすり抜けます
- ActionScriptとは異なりTypeScriptはクラス内で
const
を定義できません 2
- 無駄にクラスを作らず無駄が無い
- クラスとして作ると、使いたい定数以外にコンストラクタや
prototype
プロパティなど不要なフロパティも生成され、無駄が多いです - TypeScriptの
namespace
は只のObject
なのでシンプルです
ストリングリテラル型 + namespace + const
TypeScript1.8から ストリングリテラル型 が入りました。イベント名のような文字列で指定するものを型チェックできるもので、より厳密なチェックができます。
type SomeEvent = "click" | "load" | "mousemove";
function doSomething(ev: SomeEvent){}
doSomething("click"); //compile ok
doSomething("klik"); //compile error
ただし、この厳密さは上記のものにも適応され、そのままではコンパイルエラーになります。
doSomething(EventName.CLICK); //compile error
ストリングリテラル型にも対応したイベント名の管理方法は以下になります。
/**
* イベント名を列挙したネームスペース(ストリングリテラル型ver.)
*/
export namespace EventName{
export const LOAD:"load" = "load";
export const CLICK:"click" = "click";
export const MOUSE_MOVE:"mousemove" = "mousemove";
}
doSomething(EventName.CLICK); //ok
文字列のEnumがないTypeScriptで、文字列Enumっぽいことをするには現状これが一番近いと思います。
まとめ
- TypeScriptのイベント名は
namespace
+const
の管理方法もある - 無駄が少なく、再代入防止というメリットがある
- ストリングリテラル型+
namespace
+const
で文字列のEnumっぽくチェックと管理ができる
-
特にTSで名前はついてないと思いますが、ASではそう呼ばれていたと記憶しています ↩
-
ただし、近い将来
readonly
がプロパティに対して付けられるようになるので、メソッド等と一緒に管理するならその方法もありだと思います ↩