はじめに
TypeScriptを最近学んだので振り返り記事になります。
TypeScript4.9の内容なので今更感はありますがご了承下さい。
汎用例
通常犬、猫の種類を表現する時はbreed、その他の動物ではspeciesと呼びます。
そのため以下のように個別のプロパティを設けて実装することにしました。
type Dog = {
type: "dog";
breed: string;
};
type Cat = {
type: "cat";
catBreed: string;
}
type Hamster = {
type: "hamster";
species: string;
};
type Animal = Dog | Cat | Hamster;
プロパティ毎にコンソールの出力内容を変更したいとします。
const printAnimal = (animal: Animal) => {
switch (animal.type) {
case "dog":
console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
break;
case "hamster":
console.log(`こちらのハムちゃんの種類は${animal.species}です`);
break;
/** Catの分岐を書き忘れた。。。 */
}
}
このようにIf文やswitch文を用いて実装するとパターン漏れが発生して、
テスト時にやっと気づくみたいな事がよくあります。
TypeScript 4.9からは便利なsatisfies
演算子なるものが、
実装されて以下のようにコンパイル時に気づくことができます。
satisfies
は直訳すると必要性を満たす
です。
const printAnimal = (animal: Animal) => {
switch (animal.type) {
case "dog":
console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
break;
case "hamster":
console.log(`こちらのハムちゃんの種類は${animal.species}です`);
break;
default:
// 型 'Cat' は想定された型 'never' を満たしていません。ts(1360)
animal satisfies never;
break;
}
}
以前はnever型の特性を利用して以下のようなコードを書いていましたが、
不要な変数に値をセットしていたり直感的に理解しにくいコードになってしまうため、
satisfies
演算子を用いて網羅性チェックをする事をお勧めします。
const printAnimal = (animal: Animal) => {
switch (animal.type) {
case "dog":
console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
break;
case "hamster":
console.log(`こちらのハムちゃんの種類は${animal.species}です`);
break;
default:
// 型 'Cat' を型 'never' に割り当てることはできません。ts(2322)
const check:never = animal;
break;
}
}
参考文献