始めようTypeScript

この記事は [アイスタイル Advent Calendar 2022](https://qiita.com/advent-calendar/2022/istyle) 5日目の記事です。

## はじめに
はじめまして。今年の7月にアイスタイルグループにジョインさせていただいたshirakです。

エンジニアとしてのキャリアは10年ほどで、インフラ・アプリ・マネジメントとフルスタックに活動してきました。

先日、アイスタイルグループ内でTypeScript入門者向けのLT発表をさせていただいたので、その内容を記事にしたいと思います。

* これからTypeScriptを学びはじめたいエンジニアの方
* プロダクトとプロジェクト運営の品質を高めたいマネージャーの方
* 「JavaScriptか、TypeScriptか。それが問題だ。」と感じている技術選定者の方
* TypeScriptを布教するための平易な入門記事を探している方

様々な立場の方に向けて、TypeScriptの概要を短時間で把握していただくことを目指した内容になります。
ぜひ、最後までお付き合いください。


## 目次
* Why TypeScript??
    * JavaScriptのつらみ
    * TypeScrpitの目指すゴール
    * 型があると何が嬉しいのか
* What is TypeScript??
    * TypeScriptの仕組み
    * TypeScriptがもたらす価値
* How to TypeScript??
    * Hello TypeScript（新規導入する場合）
    * 既存プロジェクトをTypeScript化する際の考慮ポイント


## Why TypeScript??

### JavaScriptのつらみ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/1334c35a-4698-afbd-8689-67f5e82ec7e2.png)
業務でプレーンなJavaScriptのプロダクト開発を担当すると、結構な頻度でツライなーと感じることがあります。

* 構造化されていない***スパゲッティコード***
* 自由なプロパティ追加・削除によって生まれる特級呪物: ***中身が謎のオブジェクト***
* 落ちて初めて気づく***事前検知できないエラー***
* これらのつらみが引き起こす***新規参画者が負担する高い学習コスト***

JavaScriptは、いまやフロントエンドからバックエンドまでカバーし、[Githubのプロジェクト数ランキング](https://octoverse.github.com/2022/top-programming-languages)でも不動の1位となっている人気・実力を兼ね備えたプログラミング言語です。
ただ、その高い表現力と柔軟性ゆえに、上述したようなつらみが顕在化しやすいです。

こうしたつらみを解決する有力なツールがTypeScriptです。
TypeScriptは、2021年から2022年の間にGithubでの利用プロジェクト数が前年比37.8%も増加しており、大変注目を集めています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/93af9f35-0109-b295-00a2-9cbe1d4afb54.png)



### TypeScriptの目指すゴール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/fc22511d-6ec4-6cc5-0c66-34f281f9aa2b.png)
そんな急成長中のTypeScriptが目指すゴールは、***JavaScriptに任意の型システムを追加する***というものです。
興味のある方はぜひ[TypeScript Deep Dive(日本語版)](https://typescript-jp.gitbook.io/deep-dive/getting-started/why-typescript)をご覧ください。
TypeScriptの基礎から背景・思想までわかりやすく体系的に解説されています。

***型システム***とは要するに、JavaやC言語などで出てくるクラスやインターフェースといった***型付け要素***を用いてプログラミングする手法・システムのことです。

TypeScriptはJavaScriptで書かれたコードに型安全性をもたらします。
特に重要な点は、***TypeScriptはJavaScriptの完全なスーパーセット(上位互換)であり、JavaScriptにコンパイラやIDEで使う型情報が付いただけのもの***だということです。

つまり、あなたの手元にあるJavaScriptのコードはすでにTypeScriptであるということです。

なので、今初めてTypeScriptを知ったという方も、安心してこのまま読み進めてください。
あなたはすでにTypeScriptを使っているのですから。


### 型があると何が嬉しいのか
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/cab94d8b-f05a-1001-daea-c4843e3873f2.png)
TypeScriptがどんなものであるかという話をする前に、TypeScriptがもたらす「型」があると何が嬉しいのかまとめてみました。

* 開発者にとってのメリット
    * 精度の高いコード補完が効くようになる
    * その結果、生産性が大きく向上する
* レビュアーにとってのメリット
    * コードの可読性が高まる
    * コードチェッカーを利用して機械的に不具合を検知できる
    * レビュー時、仕様に集中しやすくなる
* PM（プロジェクトマネージャー）にとってのメリット
    * 型安全なプロダクトになるため、品質が良くなる
    * 新規参画者の学習コストが抑えられることにより要員計画通りにプロジェクト運営しやすくなる
* BO（ビジネスオーナー）にとってのメリット
    * プロダクトの品質とチームの生産性が向上するため、開発の費用対効果が高まる
    * より高速なPDCAサイクルを回せるようになり、ビジネスKPIを達成しやすくなる

もちろん、デメリットとしてTypeScript自体をキャッチアップするための学習コストや初期導入コストなどが挙げられますが、総合的に見てメリットが大きくなる場合の方が多いと感じています。


## What is TypeScript??

### TypeScriptの仕組み
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/2898fabd-9d6d-7bf7-778b-727ce68748a7.png)
それでは、簡単にTypeScriptの仕組みを紹介したいと思います。
TypeScriptは***tsファイルをコンパイルしてjsファイルを生成するツール***です。

前項でお伝えした「TypeScriptはJavaScriptの完全なスーパーセット(上位互換)である」というのは、この仕組みによって実現されています。

TypeScriptを用いた開発の流れは次のようになります。

* 開発者はhoge.tsファイルに対してコードを書いて実装作業を行う
* TypeScriptのコンパイラがtsファイルをコンパイルしてjsファイルを生成する(hoge.tsからhoge.jsが作られるイメージ）
* サーバは生成されたjsファイルを実行する

このような開発フローがチームにもたらすメリットがいくつかあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/2448bd1b-cd92-c4fa-d5d4-65076c9bb6f5.png)
まず、開発者に対しては、型を利用したコーディングができることによる型安全な開発環境がもたらされます。
そして、型を使って書かれたコードは自己説明的で理解しやすく、保守しやすいものになります。
そして、TypeScriptのコンパイラが事前に静的な型チェックや文法チェックを行ってくれるため、サーバ上で実行する前に実装不備を検出することができます。
なお、デフォルトの設定ではTypeScriptのコンパイラはコンパイルエラーを検出した場合でもそれを無視してjsファイルを生成するため、部分的・段階的なTypeScriptへの移行が可能な点も見逃せません。
最終的に出力されるjsファイルは、実はモダンな（ES6以降のバージョンで計画されている多くの機能が使える）形に変換されて出力されるため、TypeScriptを導入することによって新しいバージョンのJavaScriptに提供されている便利な機能を利用できるようになります。


### TypeScriptがもたらす価値
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985722/871d75db-606a-238d-a09e-5ef56c5d063b.png)
まとめると、TypeScriptがもたらす価値は次の4点に集約されると思います。

* 型安全性
    * 実装を縛りやすく、コードベースに型システムによる秩序を与える
* コードの自己文書化
    * 型情報とともにコードが書かれることで、読みやすく理解しやすい状態になる
    * IDEが提供する強力なコード補完機能を利用できるようになる
* コード品質の向上
    * 型システムによってコード品質が向上し、再利用性も高まる
* 開発効率の向上
    * リファクタリングの作業効率が上がり、コードを健全な状態に保ちやすくなる
    * 静的エラー解析によって実行前・テスト前にコード不備を検出しやすくなる


## How to TypeScript??
### Hello TypeScript（新規導入する場合）
それでは最後に、実際にTypeScriptを始める方法について紹介します。

やることは、***typescriptをインストールして.tsファイルを書き始めるだけ***です。
```bash
$ npm install -g typescript
$ echo “console.log(‘hello TypeScript!!’);” > hello.ts
$ tsc .
$ node hello.js    # hello TypeScript!!
```

まず、npmやyarnなどでtypescriptをインストールします。
※グローバルにインストールするのが気になる場合は`npm install typescript --save-dev`でも大丈夫です。

そして、任意のJavaScriptコードを書きます。
保存するファイルの拡張子を.tsにしておきます。
上記の例では、コンソールに"hello TypeScript!!"と出力するだけの処理をhello.tsファイルに書いています。

tscコマンドを実行し、TypeScriptのコンパイラを起動するとすぐにhello.jsファイル（拡張子がjsになっています）が生成されます。

このhello.jsを実行するとコンソールに"hello TypeScript!!"と出力されるのを確認できます。

#### 依存ライブラリがある場合、typesyncが便利
```bash
$ npm install -g typesync   # 事前にtypesyncをインストール
$ npm install               # プロジェクトの依存ライブラリをインストール
$ npx typesync              # package.jsonから必要な型定義モジュールを推測
$ npm install               # 型定義モジュールをインストール
```

TypeScriptで型安全な開発環境を作るには、依存ライブラリに対しても型定義が必要です。

もちろん、一から自分で用意する必要はなく、メジャーなJavaScriptライブラリにはすでに型定義モジュールが提供されています。

とはいえ、一つ一つ型定義モジュールをインストールするのは手間なので、typesyncを利用するのがおすすめです。

[typesync](https://www.npmjs.com/package/typesync)は、package.jsonから必要な型定義モジュールを推測して自動的にインストールしてくれるため、開発環境を構築する際に非常に便利です。


### 既存プロジェクトをTypeScript化する場合
すでに開発中 or 運用中のJavaScriptプロジェクトをTypeScript化する場合、移行方法を検討する必要があります。

プロジェクトの規模や状況に応じて、どのように移行すべきか個別に検討しましょう

#### 移行方法の検討観点
1. 移行ツールの利用判断
1. ts移行対象の選定
1. テスト方法の確認
1. CICDパイプラインの確認
1. TypeScriptへの移行ポリシーの周知

##### 1. 移行ツールの利用判断
Airbnbが開発した[ts-migrate](https://www.npmjs.com/package/ts-migrate)のように、一括でjsをtsに変換するツールがありますので、こういった自動ツールを利用した移行を行うか（できるか）の判断をしましょう。

既存のJavaScriptコードをTypeScriptにすると、最初は大量の型チェックエラーが検出される場合があります。
大量のエラーがある状態のままだと、型チェックによるバグ検出が困難になってしまうため、とりあえず型チェックエラー箇所を手動でひたすらany型にするとか`@ts-ignore`アノテーションを付けて回るとかして型チェックエラーを回避する必要があります。

こうした面倒な単純作業を自動で行うことで、とりあえずTypeScript化を実現してくれるのがts-migrateです。
もちろんts-migrateを適用しただけではプロジェクト固有の型定義が存在しませんので一つずつ追加していく必要があります。
ですが、すばやくTypeScriptを始められる環境を作れることは大きいです。

移行ツールが使える場合は積極的に利用していくのが効率的だと思います。

##### 2. ts移行対象の選定
既存のプロジェクトが複数のモジュールに分かれていたり、今後変更される予定がないレガシーコードが存在するような場合、TypeScript化する範囲を適切に選択することも重要です。

TypeScriptはJavaScriptの完全な上位互換なので、すべてのコードをTypeScriptに移行する必要はありません。
古いコードや使用頻度の低いロジックはTypeScript化の対象外とするなど、移行対象プロジェクトの規模が大きい場合、移行ポリシーを明確にすることが重要です。


##### 3. テスト方法の確認
TypeScript化の作業によって不具合やバグが混入していないかを確認するため、あらかじめリグレッションテストの方法を検討する必要があります。

単体テストやE2Eテストの環境が整っている場合はそれを利用できるか、単純に手動で動作確認するのか、などTypeScriptへの移行作業が正しく完了したことを判断できるようにしておきましょう。


##### 4. CICDパイプラインの確認
TypeScript化が完了すると、それ以降のリリース時にTypeScriptのコンパイル作業が必要になります。

既存のCICDパイプラインがある場合は、ビルドスクリプトを修正する対応が必要です。
もし既存で手動リリースを行っている場合は、リリース手順・マニュアルの更新をするなど、TypeScript化後のリリース方法について確認・周知する必要があります。


##### 5. TypeScriptへの移行ポリシーの確認
移行ツールを使えない場合など、TypeScriptへの移行作業が長期間に及ぶ場合、移行中に開発される新規機能をどのようにTypeScript化するか検討する必要があります。

事前にTypeScriptの実装ポリシーを定めて開発チームに周知することで、新規機能については最初からTypeScriptで実装するように進めるのが良いと思います。

TypeScriptのコーディング規約としては、[TypeScript Deep Dive 日本語版](https://typescript-jp.gitbook.io/deep-dive/styleguide)でも言及されています。
また、[Google TypeScript Style Guide](https://google.github.io/styleguide/tsguide.html)でGoogleがTypeScriptのルールやベストプラクティスをまとめたガイドも公開されていますので、これからTypeScriptを導入する場合はぜひ活用してみるのをオススメします。


## 最後に
ここまで読んでいただきありがとうございます。

TypeScriptを導入することによってどんなメリットがあるのか、実際に導入するにはどうしたらいいのかなど、イメージを掴んでいただけたら幸いです。
また、今回は入門向けの内容を意識してまとめましたが、より深い内容や応用的な事例についてご興味あればぜひコメントいただけると嬉しいです。

明日からも引き続きアイスタイルのアドベントカレンダーをお楽しみに！