switch文でnever typeを使ってエラー検出する処理を書いていきます。
よく見る一般的なswitch関数
enum SampleEnum {
hoge,
popo,
}
function doSwitch(value: SampleEnum): boolean {
switch (value) {
case SampleEnum.hoge: return true;
case SampleEnum.popo: return true;
default:
throw new Error("default");
}
}
doSwitch関数で引数のSampleEnumの値に応じてtrue or falseを返します。
defaultはオプションのようですが、今回はnever typeを使うのもあり追加しています。
今回はSampleEnumの値に新メンバーhugaを追加してみます。
enum SampleEnum {
hoge,
popo,
huga //hugaを追加
}
上のdoSwitch関数はSampleEnum.hogeとSampleEnum.popoの時のみ判別しているので
定義されていないhugaがいきなり入ってきたら default:throw new Error("default");
が呼ばれるようになります。
function doSwitch(value: SampleEnum): boolean {
switch (value) {
case SampleEnum.hoge: return true;
case SampleEnum.popo: return true;
default:
throw new Error("default"); //hugaは定義されていないので、ここが呼ばれる
}
}
これでもエラー検出できるのでいいですが、新しい値をSampleEnumに追加する度に忘れずにdoSwitch関数内の処理も更新しなくてはなりません。
なので関数の更新を忘れることも考えられます。
never typeを使ってエラーを検知する
実行時にエラーが発見できることもありますが、never typeを使うことでもっと早い段階でエラー検出ができそうです。
enum SampleEnum {
hoge,
popo,
huga //hugaを追加
}
function doSwitch(value: SampleEnum): boolean {
switch (value) {
case SampleEnum.hoge: return true;
case SampleEnum.popo: return true;
default:
//never typeを追加
const notExpectedValue: never = value;
throw new Error(notEexpectedValue);
}
}
never型のnotExpectedValueという変数を用意します。
先ほどと同様にdoSwitch関数内にはSampleEnum.hogeとSampleEnum.popoの処理が書いてあるので、その二つの値は正常に処理できそうです。
ただ新メンバーのSampleEnum.hugaが入ってきたときは、処理書かれてないからdefaultに流そう!ってことでdefaultに到達します。
そしてdefault内の処理としては、知らないメンバーがきたらエラー返してねって処理です。
const notExpectedValue: never = value;
ここのコードでは
notExpectedValueはnever型なんだからvalueなんて値代入できないよ。っと怒ってくれます。
ここで代入したかったvalueが今回でいうSampleEnum.hugaに当たります。
実際にコード上ではこんなエラーが出るかと思います。
「型 'SampleEnum' を型 'never' に割り当てることはできません。ts(2322)」
感想
doSwitch関数ないの処理追加するの忘れそうなので、never typeを使っていこうと思います!
参考記事