概要
TypeScriptで網羅性が必要な分岐が出てきた時に、assert neverを使うとコンパイル時にエラーがわかって便利です。
詳細
下記のようなswitchがあったときに、defaultでErrorをthrowしていたとします。
type Animal = "Dog" | "Cat";
function cry(animal: Animal): void {
switch (animal) {
case "Dog": {
console.log("ワン");
break;
}
case "Cat": {
console.log("ニャー");
break;
}
default: {
throw new Error("鳴かないよ");
}
}
}
AnimalにMonkeyを追加されたとき、switchにcaseを追加しないと実行時にdefaultでErrorとなってしまいます。
ただ、実行時にErrorを知るよりも、コンパイル時にErrorになって教えてくれた方が漏れがなくなって安心ですよね?
そんな時に便利なのが、assert neverを使った方法です。
const asserNever = (_x: never) => {
throw new Error("assert value");
};
type Animal = "Dog" | "Cat" | "Monkey";
function cry(animal: Animal): void {
switch (animal) {
case "Dog": {
console.log("ワン");
break;
}
case "Cat": {
console.log("ニャー");
break;
}
default: {
asserNever(animal); //型 '"Monkey"' の引数を型 'never' のパラメーターに割り当てることはできません
}
}
}
型 '"Monkey"' の引数を型 'never' のパラメーターに割り当てることはできません
上記のようなasserNeverを使用している部分でエラーとなります。
const asserNever = (_x: never) => {
throw new Error("assert value");
};
type Animal = "Dog" | "Cat" | "Monkey";
function cry(animal: Animal): void {
switch (animal) {
case "Dog": {
console.log("ワン");
break;
}
case "Cat": {
console.log("ニャー");
break;
}
case "Monkey": {
console.log("ウッキー");
break;
}
default: {
asserNever(animal);
}
}
}