ワイ「TypeScriptのエラーが読まれへん」

[**前回の記事**](https://qiita.com/Yametaro/items/ee69f2f81759b9ac39b7)の続きです。

## TypeScriptが気に入ったワイ

ワイ「TypeScript、素敵やん」
ワイ「だって、ミスったコードを書くと・・・」

![スクリーンショット 2020-10-28 10.11.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/2651a9ce-fd3b-8022-a9f4-1ccee2260393.png)

ワイ「↑こんな感じで、コンパイラが教えてくれるから」
ワイ「だいぶバグ発生率を抑えられそうや〜ん」


## しかし
ワイ「おっ」
ワイ「またエラーメッセージが出たで」

![スクリーンショット 2020-10-28 12.13.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/4c63d0d7-4b76-e367-3e42-096ff9a81cb4.png)

ワイ「**ファッ！？**」
ワイ「今度は英語やないか」
ワイ「しかもちょっと長い！」
ワイ「意味わからんで」
ワイ「Google翻訳してみよか」

> タイプの引数 '{名前：文字列; 年齢：文字列; } 'はタイプ' User 'のパラメータに割り当てることはできません。
プロパティ「age」のタイプには互換性がありません。
タイプ 'string'はタイプ 'number'に割り当てることができません。

#### ワイ「いや翻訳しても分からん！」

## 助けを呼ぶ

ワイ「ハスケル子ちゃ〜ん！」

ハスケル子「なんですか」

ワイ「TypeScriptのエラーメッセージが読まれへんねん」

ハスケル子「（いや、それは知らん・・・）」
ハスケル子「（だって英語力の問題だから・・・）」
ハスケル子「とりあえず、何をしようとしたらエラーが出たんですか？」

ワイ「ええとやな・・・」


```typescript
type User = {
  name: string
  age: number
}
```

ワイ「↑こんな感じの`User`っていう型を定義したんや」

ハスケル子「なるほど」

> - ユーザーは、名前と年齢を持っている

ハスケル子「っていうことを表してるわけですね」
ハスケル子「いいじゃないですか」

ワイ「ほんで、実際にユーザ型の変数`takashi`を作ったんや」

```typescript
const takashi = {
  name: 'たかし',
  age: '36'
}
```

ハスケル子「なるほど」

ワイ「そんで、次は関数を作って、実行しようとしたんや」
ワイ「引数として`User`型の値を受け取る関数や」

```typescript
const makeProfileText = (user: User): string => {
  return `${user.name}（${user.age}歳）`
}
```

ワイ「↑こんな感じで`makeProfileText`って関数を作ったんや」
ワイ「そんでこの関数に、`takashi`というユーザを渡して・・・」

```typescript
const profileText = makeProfileText(takashi)
```

ワイ「↑こんな風に実行してやると・・・」

> `'たかし（37歳）'`

ワイ「↑こんな感じの、**プロフィール用のテキスト**を返してくれるっていう」
ワイ「そんな関数や」
ワイ「でも、ここでさっきの・・・」

![スクリーンショット 2020-10-28 12.28.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/65e9d009-ea70-0576-08d2-389098ba2b85.png)


ワイ「↑訳わからんエラーが出てもうたんや・・・」
ワイ「`takashi`いう変数が問題みたいや・・・」

ハスケル子「たぶん、一行ずつ読んでいけば分かりますよ」
ハスケル子「英語にビビらず、一行ずつ読んでいきましょう」

## 一行ずつ読んでいく

> Argument of type '{ name: string; age: string; }' is not assignable to parameter of type 'User'.

ハスケル子「↑まずはここは・・・」

> `User`型の引数として
> `{ name: string; age: string; }`をぶち込むことはできまへん！

ハスケル子「↑こんな意味です」

ワイ「なるほどな」
ワイ「`{ name: string; age: string; }`ってのは何のこと？」

ハスケル子「それは`takashi`という変数の型ですね」
ハスケル子「つまり」

> `User`型の引数として`takashi`をぶち込むことはできまへん！

ハスケル子「↑ってことです」

ワイ「なるほどな」

ハスケル子「そして次の行は・・・」

> Types of property 'age' are incompatible.
>
> `age`というプロパティの型が合ってまへんねん！

ハスケル子「↑ってことですね」
ハスケル子「そして最後の行は・・・」


> Type 'string' is not assignable to type 'number'.
>
> **文字列型**の値は、**数値型**にはぶち込めまへん！

ハスケル子「↑こうですね」
ハスケル子「まとめると・・・」


> `User`型の引数として`takashi`をぶち込むことはできまへん！
> `age`というプロパティの型が合ってまへんねん！
> **文字列型**の値は、**数値型**にはぶち込めまへん！

ワイ「なるほど」
ワイ「要約すると・・・」

> `takashi`の`age`が`string`だから、アカン！

ワイ「ってことか」

```typescript
const takashi = {
  name: 'たかし',
  age: '36'
}
```

ワイ「あ、ほんまや」
ワイ「`takashi`の`age`が**文字列**になってしまってるわ」
ワイ「`User`型の`age`は`number`のはずやのに」

ハスケル子「そういうことですね」
ハスケル子「一行ずつちゃんと読めば、意外と簡単ですよね」

ワイ「まあ、なんとかなりそうやな」

## 下の行から読んで行くのも吉

ハスケル子「具体的に修正すべきポイントは**一番下の行**に表示されているので」
ハスケル子「**下から読む**のも良いと思います」

> **文字列型**の値は、**数値型**にはぶち込めまへん！
> `age`というプロパティの型が合ってまへんねん！
> `User`型の引数として`takashi`をぶち込むことはできまへん！

ハスケル子「↑なんか読みやすくないですか？」

ワイ「ほんまや」

## できるだけ型を書こう

ハスケル子「あと、`takashi`にも明示的に型を書いたほうが良いですよ」

ワイ「どういうこと？」

```typescript
const takashi: User = {
  name: 'たかし',
  age: '36'
}
```

ハスケル子「↑こういうことです」
ハスケル子「こうしておくと・・・」

![スクリーンショット 2020-10-28 14.51.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/295452/2b230246-1636-e288-7a7d-eeb2e4970868.png)

ワイ「おお、`takashi`の`age`がアカンってことが一目瞭然やな」

ハスケル子「そうなんです」
ハスケル子「型情報を書かなくても、ある程度はTypeScriptくんが**気を利かせてくれる**んですが」

> 「`takashi`は`User`型の値です！」
> 「私はそういうつもりでこのコードを書いてます！」

ハスケル子「っていう風に、能動的に型を書いて宣言したほうが」
ハスケル子「より正確なエラーメッセージを表示してもらえる可能性が高くなりますね」

ワイ「なるほどなぁ」

## まとめ

> `Hoge`型の引数として`fuga`をぶち込むことはできまへん！
> `piyo`というプロパティの型が合ってまへんねん！
> `aaa`型の値は、`bbb`型にはぶち込めまへん！

- TypeScriptでは↑この形式のエラーメッセージが表示されることが多い。
- 英語だし文が長めだし、怯みそうになるけど、一行ずつ読めば意外と何とかなる。
- **下の行から読んで行く**と、直すポイントが分かりやすいかも。
- 型は能動的に書いていこう。そのほうがエラーの意味が分かりやすくなるよ。

ワイ「↑ってことやな！」

ハスケル子「ですね！」

**〜おしまい〜**