3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

TypeScriptで網羅性が必要な分岐が出てきた時に便利なtips

Posted at

概要

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);
    }
  }
}

分岐を網羅しているとエラーとなることはありません。

結論

コンパイルの時に網羅しなければいけないところを知れて分岐の追加忘れを防げるのが便利すぎる

3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?