union型(string | number)のメソッド呼び出しで型エラーになる理由
string | numberのようなunion型の値に対して、片方の型にしか無いメソッド(toUpperCaseなど)を呼び出そうとすると、もう一方の型に無いことを理由にエラーになります。typeof等で型を絞り込む(narrowing)必要があります。
エラーメッセージの読み方
main.ts(2,16): error TS2339: Property 'toUpperCase' does not exist on type 'string | number'.
main.ts- ファイル名
2- 行番号
16- 列番号 — この位置でtscが検査に失敗しました
TS2339- エラーコード — 検索するとTypeScriptの解説が見つかります
Property 'toUpperCase' does not exist on type 'string | number'.- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 function describe(value: string | number): string { 2 return value.toUpperCase(); ^ 3 } 4 console.log(describe("hi"));
main.ts(2,16): error TS2339: Property 'toUpperCase' does not exist on type 'string | number'.
valueはstring | number型です。toUpperCaseはstringにしかないメソッドなので、narrowingせずには呼べません。
直し方: toUpperCase を toString にします。
広告
広告スロット(未設定)
パターン2
1 function format(value: string | number): string { 2 return value.toFixed (2); ^ 3 } 4 console.log(format(3.14159));
main.ts(2,16): error TS2339: Property 'toFixed' does not exist on type 'string | number'.
toFixedはnumberにしかないメソッドです。string | number型のままでは呼び出せません。
直し方: toFixed を toString にします。
パターン3
1 function label(value: string | boolean): string { 2 return value.toUpperCase(); ^ 3 } 4 console.log(label(true));
main.ts(2,16): error TS2339: Property 'toUpperCase' does not exist on type 'string | boolean'.
toUpperCaseはbooleanには存在しません。string | boolean型のままでは呼び出せません。
直し方: toUpperCase を toString にします。
よくある誤解
「文字列を渡すつもりだから大丈夫」という呼び出し側の意図は、TypeScriptの型チェックには伝わりません。union型のまま扱う限り、tscは「numberが渡されるかもしれない」という前提でチェックします。
まとめ
union型(string | number)のメソッド呼び出しで型エラーになる理由は中級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。