1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

TypeScriptのEnumの何がダメなのか

Posted at

TypeScriptのEnumの何がダメなのか

TypeScriptのEnum使うのは避けようという事を耳にしたのできちんと調べた
自分なりに脱却案を記した

数値型Enum

enum.ts
enum Sex {
  male,
  female
}

console.log(Sex.male) //0
console.log(Sex[0]) //male

数値は自由に選択可能

enum.ts
enum Sex {
  male = 1,
  female
}

console.log(Sex.male) //1
console.log(Sex.female) //2
console.log(Sex[1]) //male

問題点

コンパイルエラーにならないので気づかずに999を代入できてしまう。むかつく。

enum.ts
enum Sex {
  male = 1,
  female
}

const hoge: Sex = 999 //コンパイルエラーにならない

console.log(hoge) //999
console.log(Sex[hoge]) //undifined

EnumはTypeScriptの独自機能なのでコンパイルされるとこうなる

enum.js
var Sex;
(function (Sex) {
    Sex[Sex["male"] = 1] = "male";
    Sex[Sex["female"] = 2] = "female";
})(Sex || (Sex = {}));

文字列型のEnum

文字列を指定することができる。文字列での代入ができないので変更があった場合に最小限で済む。

enum.ts
enum Sex {
  male = "男性",
  female = "女性"
}

const hoge: Sex = Sex.male
const fuga: Sex = "男性"  //コンパイルエラー

console.log(hoge) //男性
console.log(Sex["male"]) //男性

以下でもできる。コンパイル結果は変わらないのでキーが文字列で記述することが明示的なことから個人的にはこちらが良い気がしてる
Enumを使うとするならばですが。。。

enum.ts
enum Sex {
  "male" = "男性",
  "female" = "女性"
}
console.log(Sex["male"]) //男性
enum.ts
var Sex;
(function (Sex) {
    Sex["male"] = "\u7537\u6027";
    Sex["female"] = "\u5973\u6027";
})(Sex || (Sex = {}));

const Enum

enum.ts
const enum Sex {
  male = 1,
  female
}

const hoge: Sex = Sex.male

constを入れることによって使用時にインライン化してコンパイルされる。

enum.ts
const hoge = 1 /* male */;

Enumがダメなところ

全般

  • 数値型Enumが型安全でない
    • 上記で示した通り

constでないEnum

constでないEnumの欠点は2つ

  • そもそもTypeScriptの概念に合っていない
    • TypeScriptはJavaScriptとの互換性があり静的型付けができることがコンセプトなのに互換性がない
  • Tree-shakingできない
    • コンパイル時に即時関数を作り出すので使われているかどうか判断できない

const Enum

  • Babelでのトランスパイルができない
    • 方法はあるがプラグインを入れたりなど手間が生じる

Enum脱却

じゃあどうするか…
コンパイル時にオブジェクトを生成するんだったら
初めからオブジェクト作ればよくないか!?ってことで以下にした

index.ts
const sexNumber = {
  male: 0,
  female: 1
} as const

console.log(sexNumber["male"]) //0

const sexString = {
  male: "男性",
  female: "女性"
} as const

console.log(sexString["male"]) //男性

脱却できたかと思う。
ご意見があればコメントお願い致します!!

参照

さようなら、TypeScript enum
TypeScriptのenumを使わないほうがいい理由を、Tree-shakingの観点で紹介します

1
2
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
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?