JavaScriptやったことない人間がTypeScriptに初挑戦した
最近の開発で、Webアプリのプロトタイプを作る仕事がありました。今も続けていますが。
その中で、ほとんどWebのフロントエンドをやったことがない人間(筆者)が、TypeScriptを使ってみたので、その感想と紹介をしてみます。
認識違いはありそうなので、誤り等はご容赦ください。
筆者経験(担当時点)
- バックエンド(サーバーサイド)は経験あり。Web APIを作れと言われたら作れる
- フロントエンドは、ブラウザはほぼ経験なし。
WPFはかなりいじっているし、UWPに関してもそれなりに知っている - いわゆる
MVCフレームワークに基づいたWebアプリの仕組みについては理解している
既存のフレームワークだけだと、動的ページを作るのが難しいことは知っている、ということ
経緯
条件を複数指定して、検索結果を表示する画面を作る必要がありました。見た目はbootstrap4で繕っています。
単純なものであれば、固定入力欄を用意して、フォームでリクエスト飛ばして、ページ遷移させて結果を表示するという形で実現できます。一度それで作りました。
しかし、条件自体を追加しながら検索したい、という要望が発生する*1のは容易に想像できるため、その機能を前提とした作りに挑戦しよう、と思いました。
そこで、
- 検索条件を
JSONに詰め込んで、リクエストとしてサーバーに送る - 検索結果をレスポンスで送り返す
- そのままページ遷移させずに表示
という作りに挑戦してみました。
クソ下手な絵(ペイント3D作)

…慣れた人にとっては大したことはないんですよねきっと。
仕組み上、どう考えてもJavaScriptを使う必要がありますが、あまり良い印象を持っていないため、TypeScriptで挑戦してみよう、というのが、今回使った経緯です。
余談ですが、バックエンドはDjangoで、Django-Rest-Frameworkを使ってWeb APIを作りました。それはそれで苦労しましたが、仕組みそのものは理解していたので、大したことはなかったです。
このときに、検索処理をフォームからでもREST API経由でも使えるように、Repository等を利用して処理を一つにしたのは、まあいいでしょう。
TypeScript使用準備
開発にはVisual Studio Codeを使用しています。
が、そもそもTypeScriptで作ったスクリプトを動かすには、JavaScriptに変換(トランスパイル)する必要があります。
typeScriptのコンパイラを簡単に使うには、まずNode.jsをインストールし、一緒に入ってくるnpmを使って
npm install -g typescript
とすればよいです。*2
tsconfig.json作成
コンパイル自体は、上記のようにインストール後に
tsc index.ts
のようにファイルを指定すると行えます。
ただ、実際に開発する場合は、生成後のJavaScriptファイルを置く場所を変更したり、TypeScript自体をデバッグできるようにしたり、フォルダ内にあるスクリプトを一括でJavaScriptに変更したい等あります。
そのときは、TypeScriptの開発フォルダで
tsc --init
と入力し、tsconfig.jsonを生成します。
私が有効にした設定は、
{ "compilerOptions": { //途中省略 "declaration": true, "sourceMap": true, "outDir": "", //実際にはJavaScriptの出力先を指定 //以下省略 } }
という感じです。これをやった後は、tsconfig.jsonがあるフォルダでtscコマンドを実行すると、設定したとおりにJavaScriptが生成されます。*3
単にWebページから呼び出すだけなら、この程度の環境設定で使えるようになります。
TypeScriptのコーディング
これは、ここ良かったなぁ、と思ったところを挙げていきます。
型ヘルプ(Intellisense)が充実している
これは非常に大きかったです。
例えば、JavaScriptで
const btn = document.getElementById('search')
という処理を書くと、見た目上、btnはHTMLElementとして扱われますが、実際は要素に応じた型です。そして、開発者にとっては、IDを指定した時点で、それが何なのかわかっています。
そこで、TypeScriptでは、
const btn = <HTMLButtonElement>document.getElementById('search');
のように書くことでキャストされ、ソース上要素型を明示できます。
他にも、動的に要素を作成する場合、
values.forEach(v => { const item = document.createElement("a"); item.classList.add("list-group-item", "list-group-item-action", "list-group-item-primary"); item.href = v.url.href; item.text = v.name; item.target = "_blank"; resultElem.appendChild(item); });
というソースがある場合に、

というように、作っているのはAnchor要素だよ、というのを判断して出してくれます*4。
筆者のようなJavaScript初心者でも、どの型にどのプロパティがあるのかはっきりわかることで、
- ミスを減らせる
- 使うべきプロパティが一覧化されるため、名前を調べなくてよい(要素名を知っている前提)
- 勘違いを減らせる
というような効果が見込めます。
まあ、document.createElementだと、JavaScriptであっても型解釈ぐらいはやってくれますが…getElementByIdでは恩恵にあずかれます。
慣れ親しんだクラスが使える
これは、C#やJava、Python等に慣れ親しんだ人にとっては、大きすぎる利点でしょう。
JavaScriptでは、prototypeというものを使ってクラスを表現*5していましたが、これが個人的には取っつき辛い部分でした。
TypeScriptでは、最初からクラス構文が用意されているので、大変分かりやすいです。
当然、メソッドの引数はanyではなく型指定されるので安心です。
たとえば、TypeScriptのクラスとメソッド
class SearchChanger { public Show(samples: Array<Sample>) { //処理 } }
というものがあると、JavaScriptでは
var SearchChanger = /** @class */ (function () { SearchChanger.prototype.Show = function (samples) { //処理 } }
という形に変換されます。正直、JavaScriptのほうのメソッドを手で書くように言われたら、頭がついていきません。functionがたくさん出てきて読みづらいですし。
引数のsamplesは表示対象オブジェクトのリストですが、JavaScriptではanyです。TypeScriptなら型情報を出しながら、しかも誤った要素を参照する危険性を減らしながら、安全にコーディングできます。
このおかげで、既存の知識を活用しながら、素早くコーディングできました。
躓いた点
TypeScriptは便利でしたが、躓いた点もあります。
thisの扱い
TypeScriptでは、クラス内のプロパティをthis.プロパティみたいな形で参照できます。
ただ、クラス内でHTML要素のイベントを作成し、登録した際に、そのイベント内のthisがクラスではないものが入ってきました。
ソース例はこんな感じです。(TypeScript)
constructor(combo1: HTMLSelectElement, combo2: HTMLSelectElement) { this.parentCombo = combo1; this.childCombo = combo2; this.index = this.parentCombo.selectedIndex; this.parentCombo.addEventListener("change", this.parentChanged); }
このthis.parentChanged内がおかしくなっていました。
解決策として、イベントのメソッドをアロー式にして、プロパティとして宣言すればいいというのを見つけ、そしたらうまくいきました。下記のような感じです。
parentChanged = () => { //処理 }
正直よくわかりません。きっとJavaScriptをよく知る必要があるのでしょう。
いくら便利にコーディングできるとはいえ、JavaScriptを無視できるわけではない点は、肝に銘じたほうが良いと感じています。
おわりに
あくまで感想、という内容になります。
動的ページを作るハードルは、もっと高いと思っていましたが、上に書いた検索ページ自体はWeb APIの準備やルーティング等、バックエンドの作業含めて一日で作成できました*6。
TypeScriptは、取っつきやすい、という利点があるように思っています。JavaScriptのカオスさを軽減している感じです。
しかし、はまりポイントがあるようですし、JavaScript自体の学習も必要だと思いました。
フロントエンドも楽しいです。すごく勉強になりました。