ことれいのもり

シャドウDOM実装をJavaScriptからTypeScriptに書き直してみた

はじめに

今流行っている言語といえばTypeScriptです。

JavaScriptを知っていれば習得しやすいと聞き、最近勉強を始めました。

その一歩目として、以前紹介した「シャドウDOMを追加するコード」をJavaScriptからTypeScriptに書き直してみます。

コードを見ながらTypeScriptの特徴を追っていきましょう。


以前の記事:[【JavaScript】CSSの干渉を防ぐシャドウDOMの使い方]()

ダブルクリックをしたらシャドウDOMを追加するプログラム

実際のコードで説明します。

まず、元々のJavaScriptのコードがこちらです。


document.addEventListener('dblclick', function () {
  // クリックしたテキストを取得
  const clickText = window.getSelection().toString();

  if (clickText) {
    // Shadow DOMのルートを作成
    const host = document.createElement('div');

    // ルートの中の要素を追加
    const shadow = host.attachShadow({mode: "open"});
    const span = document.createElement("span");

    // spanの中に表示する文字列
    span.textContent = "ここに" + clickText + "が入ります";

    // DOMを追加
    shadow.appendChild(span);
    document.body.appendChild(host);
  }
});


TypeScriptに直した物がこちらです。


document.addEventListener('dblclick', function (): void {
  const selection = window.getSelection();
  if (!selection) return;   // nullチェック

  // クリックしたテキストを取得
  const clickText: string = selection.toString();

  if (clickText) {
    // Shadow DOMのルートを作成
    const host: HTMLDivElement = document.createElement('div');

    // ルートの中の要素を追加
    const shadow: ShadowRoot = host.attachShadow({ mode: "open" });
    const span: HTMLSpanElement = document.createElement("span");

    // spanの中に表示する文字列
    span.textContent = "ここに" + clickText + "が入ります";

    // DOMを追加
    shadow.appendChild(span);
    document.body.appendChild(host);
  }
});


全体の流れはそのままにしつつ、TypeScript独自の仕様を追加しています。

ポイントを絞って紹介します。

型の明示

TypeScriptでは、型を指定する必要があります。


const 変数名: 型名


例えば、clickTextには文字列が入るのでstringと追加します。
書き方はコロンのあとに型を書くだけです。


// クリックしたテキストを取得
const clickText: string = selection.toString();


// Shadow DOMのルートを作成
const host: HTMLDivElement = document.createElement('div');


divタグのDOMを作っている部分は、型がぱっと見て分かりにくいです。

こういうときに役立つのが公式ドキュメントです!

document.createElement()を見に行き、「返り値」の項目をみることで何の要素を返しているか確認できます。

TypeScriptで型指定をするときは、関数についても詳しくなれそうです。

nullチェック

TypeScriptはnullを返す可能性がある場合に、構文エラーみたいな赤線が出ます。

そのため、nullチェックをしっかり行なう必要があります。


const selection = window.getSelection();
if (!selection) return; // nullチェック


例えばこの部分について。

getSelection()は何も取得できなかったときにnullを返します。

そのため、nullかどうかを判定し、nullだった場合は早期リターンするようにしました。

JavaScriptの時は一切気にしていませんでしたが、思わぬバグを引き起こす可能性を教えてくれるのはありがたいですね。

戻り値の型について

TypeScriptでは、戻り値の型を指定することができます。


document.addEventListener('dblclick', function (): void {
    ...
}


今回の場合は、何も返さないので void を指定しています。

間違えて戻り値を設定した場合、コンパイルする前にエラー表示されるので実行前にバグに気づくことができるのでこれも親切です。

終わりに

JavaScriptからTypeScriptに変更したことで、コードを書く量は増えて面倒になりました。

しかし、未然にバグの可能性を潰すことができるので結果的に良いことだと思います。


私はもともとC系の言語を触っていたこともあり、JavaScirptやPHPで型名を書かないことが逆に違和感でした。

そういう意味ではTypeScriptの書き方は慣れ親しんだものであり、好きになれそうです。

これからはTypeScriptをガンガン使っていこうと思います!!

参考にしたサイト

createElement:Document: createElement() メソッド - Web API | MDN - Mozilla

nullチェック:strictNullChecks | サバイバルTypeScript