9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【TypeScript超入門 - 型注釈編】TypeScriptでDOMを取得するときに初学者が躓きやすいポイントを分かりやすく解説

Last updated at Posted at 2021-06-24

##この記事で学べること

  • Non-null assertion operator(例: document.getElementById("〇〇")!
  • Type Assertions(例: document.getElementById("〇〇") as HTMLElement

TypeScript入門者はもちろん、JavaScriptしか触ったことのないプログラミング初心者も対象です。

Non-null assertion operatorとは

私がTypeScriptに入門して最初に躓いたのがDOM操作でした。TypeScriptはJavaScriptより型に厳しいので、同じコードを書いてもTypeScriptだと警告が出ることがあります。簡単な例を紹介します。

// Javascriptファイル
const input = document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください";
// Typescriptファイル
const input = document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください"; // 警告が出る

スクリーンショット 2021-06-22 16.42.55.png

警告文は、inputは__HTMLElement__と__null__を値として取る可能性があるオブジェクトであり、そうしたnullを取りうるオブジェクトにplaceholderプロパティは使用できない、という意味になります。

なぜnullを含むのかというと、getElementByIdメソッドの引数をタイポしていた場合それが返るからです。引数の文字列が正しいかどうか、つまりHTMLファイルの中に実際に

<input id="usernameInput">

があるかどうかまではTypeScriptコンパイラーは判断できないため、代わりにnullが返る可能性を憂慮してくれています。
このとき、引数の文字列が正しいと分かっている場合、TypeScriptコンパイラーに対して、「nullの心配はない」と教えてあげる必要があります。その方法が__Non-null assertion operator__でして、__!__を末尾につけて書きます。
スクリーンショット 2021-06-22 16.42.02.png
これで、inputはHTMLElementだけを取りうるオブジェクトになりました。ただ、placeholderにまだ警告が出てます。

Type Assertionsとは

スクリーンショット 2021-06-22 16.46.34.png

警告文はだいたいこんな意味になります。

const taro = {
 name: "太郎",
 age: 22
}

taro.language = "English" // 'language'というプロパティは'taro'に存在しない

もともとplaceholderは、__HTMLInputElementオブジェクト*またはHTMLTextAreaElement__オブジェクトがもつプロパティです。つまり、inputタグまたはtextareaタグにしか使えません。
(注: 正確には、HTMLInputElementというインターフェースが適用されたオブジェクトです)

<input placeholder="ユーザー名を入力してください。">
<textarea placeholder="ご感想など"></textarea>

一方、getElementByIdメソッドは__HTMLElement__オブジェクトを返します。これはHTMLInputElementオブジェクトとHTMLTextAreaElementオブジェクトを含むあらゆるHTML要素の親にあたるものです。

したがって、警告文は「placeholderプロパティを更新したければどういうDOMか具体的に教えて欲しい」みたいに読み替えられます。では、__Type Assertions(型注釈)__を使って「それはinputだ」と教えてあげましょう。

Type Assertionsには__as__を使う方法と__< >__を使う方法があり、どちらを使うかは好みだと思います。

const input = document.getElementById("usernameInput") as HTMLInputElement;
input.placeholder = "ユーザー名を入力してください。"
const input = <HTMLInputElement>document.getElementById("usernameInput");
input.placeholder = "ユーザー名を入力してください。"

なお、一行で書くには__( )__で囲む必要があるのと、注釈をつけることでnullの可能性は否定されるため、Non-null assertion operator は省略できます。

(document.getElementById("usernameInput") as HTMLInputElement).placeholder = "ユーザー名を入力してください。";
(<HTMLInputElement>document.getElementById("usernameInput")).placeholder = "ユーザー名を入力してください。";

ちなみにReactなどでJSXを書く場合、コンポーネントと混同しやすいため、as形式しか使えません。

9
2
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?