右クリックで開くコンテキストメニューをプログラム独自に上書きしたい時があります。そういった時メニューを開こうとした場所を知る必要があります。これを TypeScript 的に実装するならば次の様にできます。
/** 位置情報の型 */ type Position = { x: number; y: number; } /** * 左クリック、右クリック、指のタッチなどのマウスやタッチのイベントなら、その発生位置を取得する関数。 * @param MouseEvent|TouchEvent {e} イベント。何かを決定した時に発火して欲しいという意味合いでクリック、タッチのイベン */ export function getEventTriggerPosition(e: MouseEvent | TouchEvent): Position { // 返り値になる位置情報 const pos: Position = { x: 0, y: 0, }; // タッチイベントであることを TypeScript に教えるための bool 関数 // @see https://developer.mozilla.org/ja/docs/Web/API/TouchEvent const isTouchEvent = (e: MouseEvent | TouchEvent): e is TouchEvent => e.type === 'touchend'; if (isTouchEvent(e)) { // if を二段に分けることで最上部の if 文の else 側はマウスイベント確定とできる // タッチイベントならば接触点(指の数など)の一つ目の clientX, clienY を取得 // @see https://developer.mozilla.org/ja/docs/Web/API/Touch/clientX // @see https://developer.mozilla.org/ja/docs/Web/API/Touch/clientY if(e.changedTouches && e.changedTouches.length > 0) { pos.x = e.changedTouches[0].clientX; pos.y = e.changedTouches[0].clientY; } // タッチイベントが発生したが接触点がない場合(多分プログラム的にイベントを呼ばないと起きない)はノーアクション } else { // マウスイベントならば直接 clientX, clienY を取得 // @see https://developer.mozilla.org/ja/docs/Web/API/MouseEvent/clientX pos.x = e.clientX; pos.y = e.clientY; } // 取得した位置情報を返す return pos; }
余談ですがこれを手なりにコーディングするとおそらく次の様になります(私はこうなりました)。
if (isTouchEvent(e) && e.changedTouches && e.changedTouches.length > 0) { // タッチイベント用処理 } else { // クリックイベント用処理 }
こうすると changedTouhes が無い時のタッチイベントがクリックイベント用の処理に紛れ込みます。大体は undefined が 0 に変換されたり、そもそも通常のイベント発生時にはそういったプロパティの状態が存在しない、というのもあるのであまり問題になりません。しかしながら想定外の挙動の可能性が残されてまうので、そのあたり TypeScript を as や any などでごまかさずにきっちりやると安全なプログラムを作りやすいです。