前回の記事の続きです。
TypeScriptが気に入ったワイ
ワイ「TypeScript、素敵やん」
ワイ「だって、ミスったコードを書くと・・・」
ワイ「↑こんな感じで、コンパイラが教えてくれるから」
ワイ「だいぶバグ発生率を抑えられそうや〜ん」
しかし
ワイ「おっ」
ワイ「またエラーメッセージが出たで」
ワイ「ファッ!?」
ワイ「今度は英語やないか」
ワイ「しかもちょっと長い!」
ワイ「意味わからんで」
ワイ「Google翻訳してみよか」
タイプの引数 '{名前:文字列; 年齢:文字列; } 'はタイプ' User 'のパラメータに割り当てることはできません。
プロパティ「age」のタイプには互換性がありません。
タイプ 'string'はタイプ 'number'に割り当てることができません。
ワイ「いや翻訳しても分からん!」
助けを呼ぶ
ワイ「ハスケル子ちゃ〜ん!」
ハスケル子「なんですか」
ワイ「TypeScriptのエラーメッセージが読まれへんねん」
ハスケル子「(いや、それは知らん・・・)」
ハスケル子「(だって英語力の問題だから・・・)」
ハスケル子「とりあえず、何をしようとしたらエラーが出たんですか?」
ワイ「ええとやな・・・」
type User = {
name: string
age: number
}
ワイ「↑こんな感じのUser
っていう型を定義したんや」
ハスケル子「なるほど」
- ユーザーは、名前と年齢を持っている
ハスケル子「っていうことを表してるわけですね」
ハスケル子「いいじゃないですか」
ワイ「ほんで、実際にユーザ型の変数takashi
を作ったんや」
const takashi = {
name: 'たかし',
age: '36'
}
ハスケル子「なるほど」
ワイ「そんで、次は関数を作って、実行しようとしたんや」
ワイ「引数としてUser
型の値を受け取る関数や」
const makeProfileText = (user: User): string => {
return `${user.name}(${user.age}歳)`
}
ワイ「↑こんな感じでmakeProfileText
って関数を作ったんや」
ワイ「そんでこの関数に、takashi
というユーザを渡して・・・」
const profileText = makeProfileText(takashi)
ワイ「↑こんな風に実行してやると・・・」
'たかし(37歳)'
ワイ「↑こんな感じの、プロフィール用のテキストを返してくれるっていう」
ワイ「そんな関数や」
ワイ「でも、ここでさっきの・・・」
ワイ「↑訳わからんエラーが出てもうたんや・・・」
ワイ「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
だから、アカン!
ワイ「ってことか」
const takashi = {
name: 'たかし',
age: '36'
}
ワイ「あ、ほんまや」
ワイ「takashi
のage
が文字列になってしまってるわ」
ワイ「User
型のage
はnumber
のはずやのに」
ハスケル子「そういうことですね」
ハスケル子「一行ずつちゃんと読めば、意外と簡単ですよね」
ワイ「まあ、なんとかなりそうやな」
下の行から読んで行くのも吉
ハスケル子「具体的に修正すべきポイントは一番下の行に表示されているので」
ハスケル子「下から読むのも良いと思います」
文字列型の値は、数値型にはぶち込めまへん!
age
というプロパティの型が合ってまへんねん!
User
型の引数としてtakashi
をぶち込むことはできまへん!
ハスケル子「↑なんか読みやすくないですか?」
ワイ「ほんまや」
できるだけ型を書こう
ハスケル子「あと、takashi
にも明示的に型を書いたほうが良いですよ」
ワイ「どういうこと?」
const takashi: User = {
name: 'たかし',
age: '36'
}
ハスケル子「↑こういうことです」
ハスケル子「こうしておくと・・・」
ワイ「おお、takashi
のage
がアカンってことが一目瞭然やな」
ハスケル子「そうなんです」
ハスケル子「型情報を書かなくても、ある程度はTypeScriptくんが気を利かせてくれるんですが」
「
takashi
はUser
型の値です!」
「私はそういうつもりでこのコードを書いてます!」
ハスケル子「っていう風に、能動的に型を書いて宣言したほうが」
ハスケル子「より正確なエラーメッセージを表示してもらえる可能性が高くなりますね」
ワイ「なるほどなぁ」
まとめ
Hoge
型の引数としてfuga
をぶち込むことはできまへん!
piyo
というプロパティの型が合ってまへんねん!
aaa
型の値は、bbb
型にはぶち込めまへん!
- TypeScriptでは↑この形式のエラーメッセージが表示されることが多い。
- 英語だし文が長めだし、怯みそうになるけど、一行ずつ読めば意外と何とかなる。
- 下の行から読んで行くと、直すポイントが分かりやすいかも。
- 型は能動的に書いていこう。そのほうがエラーの意味が分かりやすくなるよ。
ワイ「↑ってことやな!」
ハスケル子「ですね!」
〜おしまい〜