サンプルコード
数値列挙型の双方向マッピングによる予期しない動作
キーから値、値からキーへの双方向マッピングが自動的に生成される。
そのため、列挙型オブジェクトのキー数が予想以上に増えることがある。
例えば、以下のコードでは6つのキーが生成される。
code:ts
enum PackStatus {
Draft = 0,
Approved = 1,
Shipped = 2,
}
console.log(Object.keys(PackStatus));
// 出力: "0", "1", "2", "Draft", "Approved", "Shipped"
型チェックの一貫性の欠如
数値列挙型は数値リテラルを渡せるが、文字列列挙型は文字列リテラルを渡すとエラーとなるため、数値型と文字列型で挙動が異なる。
code:ts
// 数値列挙型
enum PackStatus {
Draft = 0,
Approved = 1,
Shipped = 2,
}
const logStatus = (status: PackStatus) => {
console.log(status);
};
logStatus(PackStatus.Draft); // 問題なし
logStatus(0); // 問題なし(期待外の動作)
// 文字列列挙型
enum PackStatusStr {
Draft = "Draft",
Approved = "Approved",
Shipped = "Shipped",
}
const logStatusStr = (status: PackStatusStr) => {
console.log(status);
};
logStatusStr(PackStatusStr.Draft); // 問題なし
logStatusStr("Draft"); // エラー(期待通りの動作)
公称型と構造的型付けの不整合
TypeScriptは基本的に構造的型付けを採用している。
=> オブジェクトの構造が同じなら、異なる型でも代入可能。
列挙型は公称型として扱われる。
=> 型の名前が一致しないと代入できない
code:ts
enum PackStatus {
Draft = "Draft",
Approved = "Approved",
Shipped = "Shipped",
}
enum AnotherStatus {
Draft = "Draft",
}
const logStatus = (status: PackStatus) => {
console.log(status);
};
logStatus(AnotherStatus.Draft); // エラー