LoginSignup
1
0

More than 3 years have passed since last update.

[小ネタ] TypeScriptは列挙型をトランスパイルするときに何をしているか?

Posted at

TypeScriptの基本をPlaygroundで勉強していて以下のような列挙型のコードを実行すると

enum SEX {
    MALE,
    FEMALE,
    UNKNOWN
}
let m: SEX = SEX.MALE;

console.log(m) //=> 1
console.log(SEX[m]) //=>  "MALE"

以下のようなコードがトランスパイルされます。

"use strict";
var SEX;
(function (SEX) {
    SEX[SEX["MALE"] = 0] = "MALE";
    SEX[SEX["FEMALE"] = 1] = "FEMALE";
    SEX[SEX["UNKNOWN"] = 2] = "UNKNOWN";
})(SEX || (SEX = {}));
let m = SEX.MALE;
console.log(m); //=> 1
console.log(SEX[m]); //=>  "MALE"

パット見???となってしまったので少し詳しく見てみます。

この部分で即時関数を実行してSEXを定義しているのですが、

(function (SEX) {
    SEX[SEX["MALE"] = 0] = "MALE";
    SEX[SEX["FEMALE"] = 1] = "FEMALE";
    SEX[SEX["UNKNOWN"] = 2] = "UNKNOWN";
})(SEX || (SEX = {}));

紛らわしいのがこの部分で

SEX[SEX["MALE"] = 0] = "MALE"

これは省略せずに書くと以下のように列挙型のキーバリューを相互に入れ替えたものをそれぞれオブジェクトのアトリビュートとして定義しています。

SEX["MALE"] = 0 // の実行結果は代入した値で0
SEX[0] = "MALE"

つまり以下のようなオブジェクトが定義されます。

{
    0: "MALE",
    1: "FEMALE",
    2: "UNKNOWN",
    MALE: 0,
    FEMALE: 1,
    UNKNOWN: 2,
}

なので以下のように列挙型のキーとキーから値に両方アクセスできるのですねー :hamburger:

let m = SEX.MALE
console.log(m) // => 1
console.log(SEX[m]) // => "MALE"

playground上でやるとトランスパイルされたjs横に出てきて、すぐ見れるので初学者には良さそうです!

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