TypeScriptではEnum型よりもUnoin型を利用したほうがよいという話をよく聞きます。1 2 3
今回はEnum型からUnion型に書き換えた具体例について紹介します。
Enum型を利用した例
以下はColor
というEnum型を利用した例です。
showColor
は引数のEnumの値に対応したログを出力するメソッドです。
enum Color {
Red = "red",
Green = "green",
Bleu = "blue",
}
const showColor = (color: Color) => {
if (color === Color.Red) {
console.log("赤色です");
}
if (color === Color.Green) {
console.log("緑色です");
}
if (color === Color.Bleu) {
console.log("青色です");
}
};
showColor(Color.Red);
// 赤色です
showColor(Color.Green);
// 緑色です
showColor(Color.Bleu);
// 青色です
// NG
// Enum型で定義されていないプロパティ
showColor(Color.Yellow);
// => Property 'Yellow' does not exist on type 'typeof Color'.(2339)
// NG
// Enum型ではない
showColor("red");
// => Argument of type '"red"' is not assignable to parameter of type 'Color'.(2345)
Enum型からUnion型に書き換えた例
Enum型のCorlor
をUnion型のColor
に書き換えた例が以下になります。
showColor
の引数はEnum型からUnion型に変更されます。
// as constをつけることでプロパティをreadonlyにしている
const Color = {
Red: "red",
Green: "green",
Blue: "blue",
} as const;
// 以下のように評価される
// const Color: {
// readonly Red: "red";
// readonly Green: "green";
// readonly Blue: "blue";
// }
type Color = "red" | "green" | "blue";
const showColor = (color: Color) => {
if (color === Color.Red) {
console.log("赤色です");
}
if (color === Color.Green) {
console.log("緑色です");
}
if (color === Color.Blue) {
console.log("青色です");
}
};
showColor(Color.Red);
// 赤色です
showColor(Color.Green);
// 緑色です
showColor(Color.Blue);
// 青色です
// OK
// 文字列リテラルを直接指定してもOK
showColor("red");
// 赤色です
// NG
// Union型に含まれてない
showColor("yellow");
// => Argument of type '"yellow"' is not assignable to parameter of type 'Color'.(2345)
keyof typeofを利用してUnion型を定義する
Union型の型定義はtype Color = "red" | "green" | "blue";
でも問題ないのですが、keyof
とtypeof
を利用することで文字列リテラルを直接記述する必要がなくなります。
文字列リテラルのタイプミスによるバグも防げるので、オブジェクトからUnion型を定義する場合はkeyof
とtypeof
を活用するとよいでしょう。
keyof
とtypeof
を利用してUnion型を定義した例は以下の通りです。
const Color = {
Red: "red",
Green: "green",
Blue: "blue",
} as const;
// 以下のように評価される
// const Color: {
// readonly Red: "red";
// readonly Green: "green";
// readonly Blue: "blue";
// }
type Color = typeof Color[keyof typeof Color];
// 以下のように評価される
// type Color = "red" | "green" | "blue"
const showColor = (color: Color) => {
if (color === Color.Red) {
console.log("赤色です");
}
if (color === Color.Green) {
console.log("緑色です");
}
if (color === Color.Blue) {
console.log("青色です");
}
};
showColor(Color.Red);
// 赤色です
showColor(Color.Green);
// 緑色です
showColor(Color.Blue);
// 青色です
// OK
// 文字列リテラルを直接指定してもOK
showColor("red");
// 赤色です
// NG
// Union型に含まれてない
showColor("yellow");
// => Argument of type '"yellow"' is not assignable to parameter of type 'Color'.(2345)
type Color = typeof Color[keyof typeof Color];
がtype Color = "red" | "green" | "blue"
となる理由についてはTypeScriptの『typeof X[keyof typeof X]』の意味を順を追って理解するで詳細解説をしています。
さいごに
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!