enum

enum のイメージ

同レベルで細分化できるものを羅列したものです。例えばGitHubには Free プランと$7 の Pro プランがあるのでこれをenum化するとこうなります。

enum Plan {
  Free,
  Pro
}

型として

例えば以下Personインターフェースは人の名前とプラン情報を持ちます。planではPlanの何かしらの値を渡さなければならないので値を限定できます。

interface Person {
  name: string;
  plan: Plan;
}

const nju33: Person = {
  name: 'nju33',
  plan: Plan.Pro
};

生成後

上のPlanはトランスパイル後このように変換されます。うーん、なんだこりゃ。

var Plan;
(function(Plan) {
  Plan[(Plan['Free'] = 0)] = 'Free';
  Plan[(Plan['Developer'] = 1)] = 'Developer';
})(Plan || (Plan = {}));

コードがここだけだとして、ちと簡単にしてみます。

var Plan = {};
Plan['Free'] = 0;
Plan[0] = 'Free';
Plan['Developer'] = 0;
Plan[1] = 'Developer';

なるほど。Plan.Freeではその値が、Plan[値]ではそのプロパティ名が取れるようです。このようなオブジェクトということですね。

{
  0: "Free"
  1: "Pro"
  Free: 0
  Pro: 1
}

値からも取得できるようにすることをリバースマッピングと言うようです。

const enum

これを const enum とするとリバースマッピングが無くなり、Plan.Freeのようなオブジェクト値へアクセスの形でしか使えなくなります。

const enum Plan {
  Free,
  Pro
}

console.log(Plan.Free);

これがトランスパイルされるとこうなります。

console.log(0);

定義も無くなっています。外からの影響が無いものに使うと良いと思います。

カスタム値

=を使って値を代入することができます。

数値

enumはデフォルトで0,1...が入るようになっているのでもちろん入れれます。ただ好きな値を入れれます。

enum Plan {
  Free = 2
  Pro = 3
}

文字列

文字列を代入できます。1つでも文字列にした場合、それ以外の値も文字列を入れる必要があります。。

enum Plan {
  Free = 'Free',
  Pro = 'Pro'
}

オブジェクト

残念ながらオブジェクトは代入できません(でした)。ざっくり調べた感じでは代入できるのは上記の数値と文字列だけのようです。

オブジェクトをなんとかenumのように使いたい場合は、その列挙値をswitchに渡してその値でオブジェクト値をたぐり寄せる感じで実装する方法があります。

enum Plan {
  Free
  Pro
}

const getPlanObject = (plan: Plan) => {
  switch (plan) {
    case Plan.Free: {
      return {/*...*/};
    }

    case Plan.Pro: {
      return {/*...*/};
    }
  }
}

前の何かしら値を使う

定義の中でなら前に宣言したある enum の値を使って新しい値を作ることができます。

enum Foo {
  A = 1;
  B = A + 1;
  C = A + 2;
}

これはこのように、計算済みの値が使われる形でトランスパイルされます。

var Foo;
(function (Foo) {
    Foo[Foo["A"] = 1] = "A";
    Foo[Foo["B"] = 2] = "B";
    Foo[Foo["C"] = 3] = "C";
})(Foo || (Foo = {}));