created: 2022-08-02T09:21:07.084Z
TypeScript でカスタム例外クラスを実装する
MDNだとこんなコード例が載っている。
class CustomError extends Error {
constructor(foo = 'bar', ...params) {
// 一部割愛
super(...params)
...
this.name = 'CustomError'
...
}
}
基本的にはこれでいいのだが、TypeScript ではこれだけだと instanceof
が正しく動作しない。
つまり以下のコードが期待通り動作しない場合がある。
try {
...
} catch (e) {
if (e instanceof CustomError) {
...
}
}
これは TypeScript の Wiki にも書いてある。
instanceof will be broken between instances of the subclass and their instances, so (new FooError()) instanceof FooError will return false.
「場合がある」と書いたのは、どのバージョンの ECMAScript にコンパイルするかによって動作しないから。 ES 2015 以降の class 構文が入っているスクリプトにコンパイルする場合は↑のコードは期待通りに動作する。
ワークアラウンド
instanceof
を動作させるためには以下の1行を入れる必要がある。
Object.setPrototypeOf(this, CustomError.prototype);
class CustomError extends Error {
constructor(foo = 'bar', ...params) {
// 一部割愛
super(...params)
...
this.name = 'CustomError'
Object.setPrototypeOf(this, CustomError.prototype);
...
}
}
その他
自分の場合は webpack の mode
を development
から production
に切り替えるところでこの挙動にあたった。
mode=production
だと tsconfig#target
が勝手に変わる設定になっていたため、開発中は instanceof
が動作するけど、本番で動作しないということが起こった。