サバイバルTSを読んでのまとめ(第1回)

来月からWebアプリケーションのエンジニアとして働き始める。

転職先の会社ではTypeScriptとReactを使うようなので、最近その2つの言語を教材をいくつか用いて勉強している。

TSの方は知り合いのエンジニアの方から「サバイバルTypeScript-TypeScript入門」をお勧めしてもらったので、現在それに取り組み始めたところである。

せっかくなので学んだことを軽くまとめたいと思い、こうして記事に残している。本書の章や節に沿って学んだことをざっくりまとめていこうと思う。

book.yyts.org

「TypeScriptはスケールするJavaScript

TSはJSの上位互換としての言語であり、その違いを雑にざっくり述べると、ちゃんとスケールをするという点が挙げられる。

ではスケールとはなんぞや、というと、開発に携わる人数やコードの規模が多くなった場合でも正常に機能することを指すようだ。 こう書かれていると当然「JSだとスケールしないのか」という考えが浮かぶけれども、これはどうやら「しない(むずかしい)」という認識で正しいらしい。

こちらの記事にその理由が書かれていた。

qiita.com

JavaScript がある定常以上の規模となると、下記の理由から実装・保守の効率が非常に悪くなります。

  • 型の定義がないので、意図しない値が入ることがある。
  • null safety でないので、意図しない null や undefined が入ることがある。
  • オブジェクト指向言語だが、インターフェースやクラス定義がなく、プロパティ名を間違っていても実行時までエラーにならず、エラーになっても原因の解析に時間がかかることが多い。
  • 型やインターフェース、クラス定義がないので、エディタによる入力補完があまり受けられない。

上記はJSの弱みと言えるわけだけれど、TSは型を導入することでその弱みを補強し、かつJSと互換性を持った言語のため、上位互換の言語として広く受け入れられているようだ。

ほぼJSの弱みの裏返しだが、具体的には以下の点で補強がなされている。

  • コンパイル時に型の制約を破っている箇所を教えてくれる
  • TypeScript側で自動で型を推定・補完してくれる。そのため開発者側はあらゆる箇所に型を設ける必要はない

TypeScriptと関係のある技術

TSはその開発を助けるツールと一緒に使われることが多々ある。以下ではその具体的なツールを列挙する。

  • モジュールバンドラ

    • 複数のJSファイルやCSSファイルを一つのファイルにまとめるツール。これにより、ブラウザ側の処理を減らしてパフォーマンスを上げることができる。webpackが有名
    • まとめることでブラウザ側の処理を減らせるのは、ブラウザからサーバーへのHTTPリクエストの回数を減らせるためらしい。現在多くのブラウザ - サーバ間で採用されている通信形態はHTTP1.1である。
      この通信形態で、かつJSファイル等を一つにバンドルしていないと、表示しようとするHTML内で複数のJSを参照していた場合に、サーバに対して複数HTTPリクエストを投げてしまうため表示の速度が下がるようだ。

    • rinda1994.hatenablog.com

  • スクランナー

    • フロントエンド開発においてある決められた処理を自動化するツール。具体的には、ファイルの変更の監視やコンパイル、圧縮等のタスクを自動化している。gulpやgruntが有名
  • パッケージマネージャー

    • 必要なJSライブラリのインストールとライブラリ間の依存関係を調整してくれるツール。npmやyarnが有名

Node.js

Node.jsはJSをサーバーサイドで実行できるようにするために開発されたソフトウェア。サーバー・端末側でJSを実行するための土台の役割を果たす。

JSでサーバーに関する処理を行えるようにするため、Node.jsは例えば以下のAPIを有している。

経緯としてはそうした形だが、最近ではフロントエンドの開発でも利用されている。なぜなら上述したWebpackなどの便利なツールの多くがNode.jsを用いて書かれているものであり、それらを利用するためにはNode.jsの導入が必須となるためである。

またJSを実行する土台となる実行環境は、ブラウザとnode.jsの2つがある。ブラウザやNode.jsの内部にはv8というJSを評価して実行するためのエンジンが組み込まれているらしい。

ただ同じエンジンが入っているものの、ブラウザとNode.jsでは所持しているAPIで微妙に異なるところがある。例えばブラウザにはDOM APIという、JSからDOMにアクセスをして、タグで挟まれた要素の内容を変更するためのAPIが実装されているが、Node.jsにはない。

一方でNode.jsにはFS(File System)という、文字通りファイルシステムにアクセスをして、ファイルの読み書きを行うためのAPIが実装されている。が、同様にブラウザではこれは実装されていない。

型があることでうれしい事例

JSで以下のようなコードがあったとして・・・

function increment(num) {
  return num + 1;
}

console.log(increment('1'));

このコードを実行すると出力されるのは「11」だ。 本来1+1の演算結果を出力して欲しかったとして、それができていない理由は関数を呼び出している引数が、数値でなく文字列となっているためである。

このコードの拡張子をJSからTSに変換すると、エディタから以下のような推奨を受ける。

パラメーター 'num' の型は暗黙的に 'any' になっていますが、使い方からより良い型を推論できます。ts(7044)

そこで関数の引数の型を以下のように設定する。

function increment(num: number) {
  return num + 1;
}

console.log(increment('1'));

すると設定した型と関数を呼び出した際の引数の型が異なるためエディタから以下のように怒られる。

型 'string' の引数を型 'number' のパラメーターに割り当てることはできません。

これをこのままコンパイルしようとしても同様のメッセージのエラーが表示されて実行できず、コードを正しく修正することが可能となる。

改めてにはなるが、なので型があるうれしさとしては、こうしたコード中にある問題や危険性をコーディング・コンパイルの時点で事前に気づくことが可能な点が挙げられる。

まとめていないまとめ

Node.jsってすごい。ただ「webpackはNode.jsで書かれています」みたいな記事が割と散見されるのだけれど、Nodeって実行環境であり言語という認識で大丈夫なのかな?

参考記事