前回の記事の続きです。
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では↑この形式のエラーメッセージが表示されることが多い。
- 英語だし文が長めだし、怯みそうになるけど、一行ずつ読めば意外と何とかなる。
- 下の行から読んで行くと、直すポイントが分かりやすいかも。
- 型は能動的に書いていこう。そのほうがエラーの意味が分かりやすくなるよ。
ワイ「↑ってことやな!」
ハスケル子「ですね!」
〜おしまい〜



