【TypeScriptハンズオン③】男もすなるTypeScriptといふものを、女もしてみむとてするなり ~webアプリとして動かそう！~

# この記はなに

TypeScriptを実際に触りながらTypeScriptを説く記の**第3弾**です。
TypeScriptが **しょしんなる** 方や、TypeScriptを **いとをかし** と思っている*ひと*が対象です。

この記で、**こころよし**と思った方は、LGTM✨を**何卒よしなに願い申し上げ候**。

過去と未来👇
 1. [【TypeScriptハンズオン①】男もすなるTypeScriptといふものを、女もしてみむとてするなり](https://qiita.com/NOMURA_keibyou38/items/8cb285900291df83957a)
 2. [【TypeScriptハンズオン②】 自分だけの型を作ろう！ ](https://qiita.com/NOMURA_keibyou38/items/819e2efdfe60a4a36e50)
 3. 【TypeScriptハンズオン③】  webアプリとして動かそう！ `この記事`

@ TypeScriptをインストールしていない*ひと*はこちら👇
　 [【画像で説明】シンプルにTypeScriptを導入して使う方法](https://qiita.com/NOMURA_keibyou38/items/2cbb5971cea1ef6e83f5)
@ TypeScriptを*いとをかし*と思った*ひと*はこちら👇
　[JavaScriptを知っている方がTypeScriptをなんとなく理解するための記事](https://qiita.com/NOMURA_keibyou38/items/06a3218de3ff480ce9de)

# ハンズオン
✅ これ以降、古語は出てきません。ご安心ください
✅ VSCodeを使います

TypeScriptは、変数や関数に型を明記することで、[開発者がハッピー](https://qiita.com/atukan0930/items/e7b2f9dc70b579467de6)🤪になります。
今回は、このハッピー🤪になれるTypeScriptを使って、書いたコードを実際にブラウザ上で表示できるようにしてみましょう🙌

### プロジェクトのセットアップ
まずは、プロジェクトをセットアップする必要があるので、以下の記事にてセットアップをお願いします。
 [【画像で説明】シンプルにTypeScriptを導入して使う方法](https://qiita.com/NOMURA_keibyou38/items/2cbb5971cea1ef6e83f5)

この記事では、以下のようなコマンドを使って環境を構築しています。

```bash
$ mkdir new-typescript               // プロジェクト用のディレクトリを作成する
$ cd new-typescript                  // プロジェクト用のディレクトリに移動する
$ npm init                           // package.json（プロジェクト管理用のファイル）を作成する
$ npm install typescript --save-dev  // typescriptをインストールする
```

この結果以下のようなディレクトリ構成になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/dcfe0df6-8578-1863-2f4e-aa96a0b41073.png)

ここで、ソースコードを入れる`src`ディレクトリを用意しましょう。

```bash
$ pwd                // 現在のディレクトリが/new-typescriptであることを確認
/new-typescript
$ mkdir src          // "src"ディレクトリを作成する
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/3cf5d7c0-1e1d-0d8d-bcb9-79bdefcb5b96.png)

次に、`src`内に`.html`と`.ts`ファイルを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/2d3929e3-b915-9460-29c2-a7af146ebd54.png)

最後に、`index.html`ファイルに以下の内容をコピペしましょう。

```html
<!DOCTYPE html>
<html>
  <head>
    <title>土佐日記を読もう</title>
  </head>
  <body>
    <h1>土佐日記を読もう</h1>
    <p>次のフォームに、「紀貫之」と入力してね</p>
    <input type="text" id="text" />
    <button onclick="getBookInfo()">確定</button>
    <p id="details"></p>
    <script src="./book.js"></script>
  </body>
</html>
```

このhtmlは以下のような画面を表示します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/98b708c1-48d3-0952-b326-40d7127bac84.png)

**最終的**には、`input`フォームに`紀貫之`を入力して、`確定`ボタンを押したら、土佐日記の内容が表示されるようにしていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/d61576c3-7c15-68f3-208e-5faf5f190032.png)


### `.ts`に記述してアプリを完成する

では、実際に`.ts`ファイルにスクリプトを記述していきます。
何を記述すればいいのかを確認するために、一旦`html`を見てみましょう。

```html
<!DOCTYPE html>
<html>
  <head>
    <title>土佐日記を読もう</title>
  </head>
  <body>
    <h1>土佐日記を読もう</h1>
    <p>次のフォームに、「紀貫之」と入力してね</p>
    <input type="text" id="text" />
    <button onclick="getBookInfo()">確定</button>
    <p id="details"></p>
    <script src="./book.js"></script>
  </body>
</html>
```

1. `<input type="text" id="text" />`は、`紀貫之`と入力するフォームです。ここから、入力した文字を取得します。
2. `<button onclick="getBookInfo()">確定</button>`はクリックすると、`getBookInfo()`関数を呼び出します。
3. `getBookInfo()`関数では、`<input />`で入力したテキストを取得し、「紀貫之」というテキストが入力されたら、`<p id="details"></p>`に土佐日記の内容を表示します。

それを実現したのが、以下のコードです。（ここでは、素のJavaScriptです）

```javascript
const getBookInfo = () => {
    const inputText = document.getElementById("text").value;
    if (inputText === "紀貫之") {
        document.getElementById("details").innerText =
            "男もすなる日記といふものを、女もしてみむとてするなり。それの年（承平四年）のしはすの二十日あまり一日の、戌の時に門出す。そのよしいさゝかものにかきつく。ある人縣の四年五年はてゝ例のことゞも皆しをへて、解由など取りて住むたちより出でゝ船に乘るべき所へわたる。かれこれ知る知らぬおくりす。年ごろよく具しつる人々（共イ）なむわかれ難く思ひてその日頻にとかくしつゝのゝしるうちに夜更けぬ。廿二日（にイ有）、和泉の國までとたひらかにねがひたつ。藤原の言實船路なれど馬の餞す。上中下ながら醉ひ過ぎていと怪しくしほ海のほとりにてあざれあへり。廿三日、八木の康教といふ人あり。この人國に必ずしもいひつかふ者にもあらざる（二字ずイ）なり。これぞ正しきやうにて馬の餞したる。かみがらにやあらむ、國人の心の常として今はとて見えざなるを心あるものは恥ぢずき（ぞイ）なむきける。これは物によりて譽むるにしもあらず。";
    }
    else {
        document.getElementById("details").innerText = "？？？？？";
    }
};
```

「確定」ボタンを押した時に`document.getElementById("text").value`にて、フォームで入力した値を取得し、`inputText`に格納します。
その後、`if文`にて`inputText`に`紀貫之`が入っていたら、`document.getElementById("details").innerText`に、土佐日記の内容を代入します。

`紀貫之`でなかったら、`"？？？？？"`を入れます。

以上のJavaScriptのコードは問題ないように見えますが、`.ts`ファイルに入れるとエラーが発生します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/fab222b0-ef26-4e65-081b-9ebca2ed82d0.png)

これは、`document.getElementById("text").value`のように記述するとき、`.value`が使えるのは`<input />`要素を利用するときです。
そのため、`document.getElementById("text")`自体は`<Input />`要素であると教えてあげる必要があります。
つまり、 `<Input />`要素でないと`document.getElementById("text").value`のように記述出来ないことを示しています。

そこで、**型を設定して**あげます。

```typescript
- const inputText = document.getElementById("text").value;
+ const inputText = (document.getElementById("text") as HTMLInputElement).value;
```
ここでは、`as HTMLInputElement`というのを付け加えることで、`document.getElementById("text")`はInputの要素によるものだよーというのを明示的に表すことができます。

そのため、最終的には次のようなコードに書き換えます。

```typescript
const getBookInfo = () => {
  const inputText = (document.getElementById("text") as HTMLInputElement).value;
  if (inputText === "紀貫之") {
    document.getElementById("details").innerText =
      "男もすなる日記といふものを、女もしてみむとてするなり。それの年（承平四年）のしはすの二十日あまり一日の、戌の時に門出す。そのよしいさゝかものにかきつく。ある人縣の四年五年はてゝ例のことゞも皆しをへて、解由など取りて住むたちより出でゝ船に乘るべき所へわたる。かれこれ知る知らぬおくりす。年ごろよく具しつる人々（共イ）なむわかれ難く思ひてその日頻にとかくしつゝのゝしるうちに夜更けぬ。廿二日（にイ有）、和泉の國までとたひらかにねがひたつ。藤原の言實船路なれど馬の餞す。上中下ながら醉ひ過ぎていと怪しくしほ海のほとりにてあざれあへり。廿三日、八木の康教といふ人あり。この人國に必ずしもいひつかふ者にもあらざる（二字ずイ）なり。これぞ正しきやうにて馬の餞したる。かみがらにやあらむ、國人の心の常として今はとて見えざなるを心あるものは恥ぢずき（ぞイ）なむきける。これは物によりて譽むるにしもあらず。";
  } else {
    document.getElementById("details").innerText = "？？？？？";
  }
};
```

このコードを`book.ts`に書けたら、以下のコマンドを実行して、`.ts`ファイルを`.js`ファイルに変換します（コンパイル）。

```
npx tsc book.ts
```

これは、`html`ファイルではあくまで`.js`ファイルでないとを読み込めないので、TypeScriptのファイルはJavaScriptのファイルを変換する必要があるからです。そのため、このコマンドを実行すると、以下のようにファイルが生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/0d286365-d07b-6876-c362-e3c57f6cea8f.png)

これで、動かせるようになったので、ブラウザで表示してみましょう！

Pathをコピーして、ブラウザのURLに貼ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/0e4b9ce4-a4a8-5206-f21d-f41becc8f908.png)

問題なく動きました！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1160002/f1ba5dcd-fb8c-6d2e-7ec1-1f65d14164ec.png)


# おわりに

TypeScriptを使ったアプリの作成方法について紹介しました。
今回は、一部しか型定義を使っていないので、コードを大きくして様々な箇所で活用できるようにしておきましょう！

# 参考文献
- https://www.typescriptlang.org/docs/handbook/typescript-tooling-in-5-minutes.html#compiling-your-code
- https://qiita.com/atukan0930/items/e7b2f9dc70b579467de6