4/25 TypeScript try-catch構文のcatchの引数の型
前提
- tsconfig.jsonの設定でuseUnknownInCatchVariablesがtrueである(strictモードがtrueであればこの設定がtrueになるので同義です)
なぜ必要な知識か
- catch (err) の errの型は設定がtrueであれば、unknownになり、falseであれば、any になる
- unknownであった場合に、通常の書き方ではコンパイルエラーとなるのを解決するため
なぜそんな仕様になっているか
- 型が
Error
オブジェクトの型ではなくunknown, any型になるのは、JavaScriptの仕様上どんな値がthrowされるか分からないためです。 - throwはなんでも投げられる、つまり、unknown, any型になります。
例えば
try { throwNull (); } catch (err) { console.log(err, "が投げられた"); } function throwNull() { throw null; }
実行結果
[LOG]: null, "が投げられた"
- なんでも投げられるので、今回はnullとしましたが、プリミティブ型のものでも投げられます
- 冒頭の設定で、falseならany型になるのでコンパイルエラーにはなりませんが、trueですとunknown型なのでコンパイルエラーになります。
対処法
➀ Errorオブジェクトかどうかの条件分岐をする
② 明示的にany型にしてしまう
try { // なんらかの処理 } catch (err) { if (err instanceof Error) { res.status(500).json({ message: err.message }); } else { res.status(500).json("エラーオブジェクトでないエラーを受け取りました"); }
- catchの中でinstanceofを使い、Errorのインスタンスであるかどうかで条件分岐をしている
②
try { // なんらかの処理 } catch (err: any) { res.status(500).json({ message: err.message }); }
- any型にしてコンパイルエラーを回避している
strictモードをtrueにしてやっているのなら、➀を使った方がいいのかなと思いました。
参考
プロを目指す人のためのTypeScript入門