TypeScriptのありがたみをデザイナーさんにわかるように説明する

デザイナーさんが TypeScript と聞くと、記法が増えて難しくなるというイメージがあると思います。
確かに記法は増えますが、デザイナーさんにとっても十分メリットがあります。

この記事では、主にデザイナーさんに向けて TypeScript を使うありがたみ（メリット）を説明します。
さらに、TypeScript を動かす環境を用意して、最低限覚えておくべき書き方についても説明します。

# 前提知識

- 簡単な JavaScript なら書ける
- TypeScript について聞いたことがある
- 言われた通りのコマンドであればターミナルで実行できる

# TypeScript のありがたみ

TypeScript を使えば、単刀直入に言うと**開発が楽になります。**

- 関数の入出力がわかる
- 補完機能が強化される

といったありがたみがあります。これらについて以下で細かく見ていきます。
ちなみに、これらはもちろんエンジニアにとってのありがたみでもあります。

## 関数の入出力がわかる


例えば以下のような機能を実装することを考えてみます。

> フォームに入力された数値を昇順にソートして出力する
> ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/68e6f338-3fbf-ab46-a374-ab385fd49b7a.png)

この機能を実装するために、「数値を昇順にソートする関数」を書いてみます。

```js:JavaScript
function sortByAsc(numbers) {
  return numbers.sort((a, b) => a < b ? -1 : 1)
}
```

この関数をパッと見たときに、次のような疑問が出てこないでしょうか？

- **引数 `numbers` is 何？**
    - 数値が並んだスペース区切り文字列？  
    → `'9 87 654 321'`
    - 数値が並んだカンマ区切り文字列？  
    → `'9,87,654,321'`
    - 数値の配列？  
    → `[9, 87, 654, 321]`
- **返り値 is 何？**
    - ソート後の文字列？  
    → `'9 87 321 654'`
    - ソート後の数値の配列  
    → `[9, 87, 321, 654]`

この関数を使おうと思ったら、上記のことが明らかになっている必要があります。
明らかにするには、実際に使ってみるか、実装されたコードを読む他ないです。

今回のように1行だけのコードであればまだしも、長く複雑な関数を読まないと使い方がわからないのは正直大変です。


### 型アノテーション

`sortByAsc` 関数を TypeScript で書いてみます。

```ts:TypeScript
function sortByAsc(numbers: number[]): number[] {
  return numbers.sort((a, b) => a < b ? -1 : 1)
}
```

TypeScript では型の注釈（型アノテーション）を書くことができます。引数にどんな値を入れればいいのか、この関数からはどんな値が返ってくるのかを明示的に記述します。
**型アノテーションを使うと関数の入出力が一目瞭然になります。**

ちなみに、「単にコメントとして書いておけばよいのでは？」と思われるかもしれません。
もちろんそれでもいいのですが、**型アノテーションを使えば VSCode 上でリアルタイムに教えてくれるようになります。**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/de223b3a-8383-f352-2397-df9d177c71ed.png)
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/5530ac8f-1ecd-67ee-dda1-4c8d2e8059b1.png" width="65%">
どんな値なのかがわかるのはもちろん、間違えを教えてくれるので**バグの発生を事前に防ぐことができます。**

## 補完機能が強化される

JavaScript だと余計なものもいっぱい出てきます...
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/45ecce32-9f48-35d8-bdc6-76adf85f04ff.png" width="60%">
TypeScript なら実在するプロパティだけになります！
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/00595e77-8cbb-c439-5e28-12677f1b1672.png" width="60%">

## ここまでのまとめ 

ここまでで、TypeScript のありがたみは以下のようなものだということがわかったと思います。

- 関数の入出力がわかる
- 補完機能が強化される

そして、これらは **「型」のおかげ** です！

続いて、実際に TypeScript における型について動かしながら学んでいきます。

# TypeScript の開発環境を準備する

TypeScript を手元で書いて動かすために、まずは開発環境を用意します。

## 前提条件

以下を事前にインストールしておいてください。

- Node.js
- Visual Studio Code (VSCode)

## TypeScript を動かす方法

大きく3つの方法があります。

- [TypeScript Playground](https://www.typescriptlang.org/play/)
- tsc
- Webpack (ts-loader)

今回は tsc を使います。

## tsc を使って TypeScript を動かしてみる

TypeScript をインストールします。（最初の1回だけで OK です）

```
npm install -g typescript
```

TypeScript で書かれたファイルを用意します。

```index.ts
function sortByAsc(numbers: number[]): number[] {
  return numbers.sort((a, b) => a < b ? -1 : 1)
}

const sorted = sortByAsc([9, 87, 654, 321])
console.log(sorted)
```

TypeScript を JavaScript に変換（コンパイル）します。

```sh
tsc index.ts # index.js が生成される
```

生成された index.js を実行します。

```sh
node index.js # -> [ 9, 87, 321, 654 ]
```

これで TypeScript で書かれたファイルを動かすことができました！
このように、TypeScript は必ず JavaScript に変換して実行します。変換を行うのが `tsc` コマンドです。

TypeScript のありがたみは書かれているコードを読むだけではなかなか伝わりません。手元で書いてみたり実行してみたりすることでがわかります。
以下で説明する内容も、ぜひ手元で書いて実行してみてください。

# TypeScript の型について

以下では、TypeScript の型システムの基本的な部分について説明します。

## 取りうる値を制限してくれる

変数が取りうる値を制限できます。

```ts
let era: string = '令和'                     // string 型
let year: number = 2019                     // number 型
let heisei: boolean =  false                // boolean 型
let eras: string[] = ['昭和', '平成', '令和'] // string 型の配列
```

もちろん関数にも型を定義できます。

```ts
function sortByAsc(numbers: number[]): number[] {
  return numbers.sort((a, b) => a < b ? -1 : 1)
}
```

異なる型の値を入れるとコンパイラがエラーを吐くので、予期せぬ値が入るのを防ぐことができます。

```ts
year = '2020' // -> Type 'string' is not assignable to type 'number'.
```

## 型は作れる

[`interface`](https://typescript-jp.gitbook.io/deep-dive/type-system#intfsuinterfaces) や [`type`](https://typescript-jp.gitbook.io/deep-dive/type-system#eiriasutype-alias) を使って型を作ることができます。 

```ts
// name, start, end の3つのプロパティを持つ Era 型を定義
interface Era {
  name: string;
  start: Date;
  end?: Date; // 現在の元号の終わりはわからないので undefined を許可する
}

const reiwa: Era = {
  name: '令和',
  start: new Date('2019-05-01'),
}

const heisei: Era = {
  name: '平成',
  start: new Date('1989-01-08'),
  end: new Date('2019-04-30'),
}
```

```ts
// '昭和', '平成', '令和' のいずれかの文字列のみ許容する Era 型を定義
type Era = '昭和' | '平成' | '令和'

const era: Era = '大正' // -> Type '"大正"' is not assignable to type 'Era'.
```

## 型推論

明示的に型を書いていなくても推論してくれる機能があります。
例えば、先程の `sortByAsc` 関数の返り値の型を省略してみます。

```ts
function sortByAsc(numbers: number[]) {
  return numbers.sort((a, b) => a < b ? -1 : 1)
}
```

省略したにもかかわらず、以下のキャプチャのように `sorted` の型は `number[]` 型だと判定してくれます。これが型推論です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/63950/8ea36327-c062-0cb1-4ee8-5ed5b101b5e3.png)
これは、

- 引数の `numbers` は `number[]` 型である
- 返り値は `number[]` 型の `sort()` メソッドの結果である
- `number[]` 型の `sort()` メソッドは `number[]` 型を返す

ということから、`sortByAsc` 関数の返り値が必ず `number[]` になることを推論しています。

特に形を書くことを意識しなくても勝手に型を推論してくれるので、控えめに言ってめちゃくちゃ便利です。

# まとめ

主にデザイナーさんに向けて、TypeScript を使うと **型のありがたみ** があるということを説明しました。

- 関数の入出力がわかる
- 補完機能が強化される

また、TypeScript を動かす環境を用意して、基本的な型のことについて説明しました。

## 説明しなかったこと

この記事では TypeScript の型システムの基本的な部分について説明しました。
一方で、TypeScript のもう1つの大きな特徴である「クラスベースオブジェクト指向」については説明していません。

「クラスベースオブジェクト指向」によって、コードの疎結合性・保守性・再利用性などを高めることができ、大規模なアプリケーションにも耐えうる設計を可能とします。

どちらかというとエンジニアにとってのありがたみが大きい内容なので、この記事からは思い切って省きました。
こちらについても学びたい方は以下で紹介する記事を読んでみてください。

## TypeScript についてもっと学びたい

更に詳しく TypeScript について学んで見たい場合は、以下の記事をおすすめします。
デザイナーさんが書かれた記事のようなので、とっつきやすいと思います。

TypeScript をはじめる時のまとめ - web帳
http://www.webcyou.com/?p=5588

さらに高度なことを学びたい場合は以下をおすすめします。
かなり高度な内容ではありますが、これに書かれている内容を押さえられたら TypeScript はバッチリだと思います。

TypeScript Deep Dive 日本語版
https://typescript-jp.gitbook.io/deep-dive/