Upgrade to Pro — share decks privately, control downloads, hide ads and more …

TSKaigi 2026 - enumよ、さようなら

TSKaigi 2026 - enumよ、さようなら

このスライドは TSKaigi 2026 の登壇に使用したスライドのアーカイブになります。

チームラボでは、フロントエンドエンジニアを募集しています。
少しでも、チームラボにご興味をお持ち頂けましたら、採用ページをご覧頂けますと幸いです。
https://www.team-lab.com/recruit/

Avatar for teamLab

teamLab PRO

May 22, 2026

More Decks by teamLab

Other Decks in Technology

Transcript

  1. © teamLab Inc. 所属| 2 自己紹介 2 チームラボ パッケージチーム フロントエンドスペシャリスト

    takuma-ru たくまる 入社|2023年 4月 新卒 趣味|ごはん, つくることなんでも(このスライドテンプレも)
  2. © teamLab Inc. 僕について dathra A full-stack JS framework that

    works with the new order TC39 Signals vue-swipe-modal Modal window that can be swiped to close. (Swipeable Bottom Sheet) 3
  3. © teamLab Inc. TypeScript enum とはなにか ❌ 型だけの構文 🟢 値を持つ処理

    12 enum ZeroOrOne { Zero = 0, One = 1, } if (num === ZeroOrOne.Zero) return;
  4. © teamLab Inc. 生成コードとバンドルサイズ 15 enum ZeroOrOne { Zero =

    0, One = 1, } "use strict"; var ZeroOrOne; (function (ZeroOrOne) { ZeroOrOne[ZeroOrOne["Zero"] = 0] = " ZeroOrOne[ZeroOrOne["One"] = 1] = "O })(ZeroOrOne || (ZeroOrOne = {})); 38 B 174 B(x4.5)※ tsc, minifiyなし 
  5. © teamLab Inc. 生成コードとバンドルサイズ Tree-shaking が効きにくくなる IIFE(即時実行関数) は副作用がある可能性のあるコードとして扱われやすい バンドラは IIFE

    を 消してはいけないコード と判断しやすい 16 完成したプログラムから「どこからも使われていない不要なコード」を自動的に削除し て、ファイルを軽くする機能  Tree-shaking 
  6. © teamLab Inc. TypeScript の方針とのズレ TypeScript enum は 英雄 だった

    2012年 TypeScript 誕生 当時の JavaScript const も class もない... 名前付きの定数セットを表現するには... 19 // No const, No class... var Status = { Open: 0, Closed: 1 }; // 誰でも上書きできちゃう... Status.Open = 999;
  7. © teamLab Inc. TypeScript の方針とのズレ TypeScript Design Goals 1. エラーになりやすい構造を静的に特定する。

    2. より大きなコード片のための構造化メカニズムを提供する。 3. 生成されるプログラムに実行時オーバーヘッドを一切課さない。 4. クリーンで、慣用的で、理解しやすいJavaScriptコードを出力する。 5. 構成可能で、論理的に理解しやすい言語を作成する。 6. 現在および将来の ECMAScript 提案に沿う。 22
  8. © teamLab Inc. TypeScript の方針とのズレ TypeScript Design Goals 7. すべてのJavaScriptコードの実行時動作を維持する。

    8. 式レベルの構文追加を避ける。 9. 一貫性があり、完全に消去可能な構造的型システムを使う。 10. クロスプラットフォーム開発ツールとなる。 11. TypeScript 1.0 からの大きな破壊的変更を避ける。 23
  9. © teamLab Inc. TypeScript の方針とのズレ TypeScript Design Goals > 3.

    生成されるプログラムに実行時オーバーヘッドを一切課さない。 → IIFE という初期化コードを生成する > 9. 一貫性があり、完全に消去可能な構造的型システムを使う。 → 型だけで消える構文ではなく、JS コードを生成する 24
  10. © teamLab Inc. TypeScript の方針とのズレ TypeScript Design Goals 7. すべてのJavaScriptコードの実行時動作を維持する。

    8. 式レベルの構文追加を避ける。 9. 一貫性があり、完全に消去可能な構造的型システムを使う。 10. クロスプラットフォーム開発ツールとなる。 11. TypeScript 1.0 からの大きな破壊的変更を避ける。 26
  11. © teamLab Inc. TypeScript の方針とのズレ 消すに消せなかった 負債 > 11. TypeScript

    1.0 からの大きな破壊的変更を避ける。 → enum は TypeScript v0.9 で追加 → 互換性のため enum を消すのは難しい... → 残っていること = 現在の推奨というわけではない 27
  12. © teamLab Inc. TypeScript の方針とのズレ --erasableSyntaxOnly TypeScript 5.8 で追加されたフラグ Default:

    false TypeScript 固有の構文が実行時に意味を持たないことを要求するモード 28
  13. © teamLab Inc. TypeScript の方針とのズレ --erasableSyntaxOnly TypeScript 5.8 で追加されたフラグ Default:

    false TypeScript 固有の構文が実行時に意味を持たないことを要求するモード → 少なくとも enum は、この流れと相性が悪い... 29
  14. © teamLab Inc. enum 標準化に立ちはだかる壁 ECMAScript proposal: Type Annotations Stage

    : 1 Detail : JavaScriptコードに型注釈を書けるようにし、実行時は無視しつつ、外部 の型チェッカーが利用できるようにする提案 33
  15. © teamLab Inc. enum 標準化に立ちはだかる壁 ECMAScript proposal: Type Annotations Stage

    : 1 Detail : JavaScriptコードに型注釈を書けるようにし、実行時は無視しつつ、外部 の型チェッカーが利用できるようにする提案 34 2023 年以降 更新鈍化
  16. © teamLab Inc. enum 標準化に立ちはだかる壁 ECMAScript proposal: Type Annotations Stage

    : 1 Detail : JavaScriptコードに型注釈を書けるようにし、実行時は無視しつつ、外部 の型チェッカーが利用できるようにする提案 35 2023 年以降 更新鈍化 2023年3月 ランタイム型チェックに ブラウザ側から強い反対
  17. © teamLab Inc. enum 標準化に立ちはだかる壁 ECMAScript proposal: Type Annotations Stage

    : 1 Detail : JavaScriptコードに型注釈を書けるようにし、実行時は無視しつつ、外部 の型チェッカーが利用できるようにする提案 36 2023 年以降 更新鈍化 2023年3月 ランタイム型チェックに ブラウザ側から強い反対 enumは型注釈ではない なので対象外
  18. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 38
  19. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 39 自動初期化なし
  20. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 40 自動初期化なし const enum なし
  21. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 41 自動初期化なし reverse mapping なし const enum なし
  22. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 42 自動初期化なし reverse mapping なし const enum なし declaration merging なし
  23. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 43 自動初期化なし reverse mapping なし declaration merging なし const enum なし TS enum にはない 差分も出てきた
  24. © teamLab Inc. enum 標準化に立ちはだかる壁 Proposal for ECMAScript enums Stage

    : 1 Detail : TypeScript の enum宣言と互換性のある形式の採用を目指しています 44 自動初期化なし reverse mapping なし const enum なし declaration merging なし 現行の TypeScript enum そのものではない...
  25. © teamLab Inc. Node.js でも変化が... Type Stripping https://nodejs.org/docs/latest/api/typescript.html#type-stripping v25.2.0: stable

    → v26.0.0: --experimental-transform-types 削除 > Node.js は消去可能な TypeScript 構文のみを含む TypeScript ファイルを実行し ます。 > Node.js は TypeScript 構文を空白に置き換え... → ビルド不要で実行できる時代に! 46
  26. © teamLab Inc. Node.js でも変化が... Type Stripping > Node.js は

    TypeScript 構文を空白に置き換え... JSコード生成が必要な構文は... - Enum declarations - namespace with runtime code - parameter properties - import aliases 47
  27. © teamLab Inc. Node.js でも変化が... Type Stripping > Node.js は

    TypeScript 構文を空白に置き換え... JSコード生成が必要な構文は... - Enum declarations - namespace with runtime code - parameter properties - import aliases 48 enum を消すと 壊れる!!
  28. © teamLab Inc. なぜ、さよならを告げるべきなのか - 生成コードとバンドルに不利 - TypeScript の現在の方針と相性が悪い -

    標準化にも壁がある - Node.js の Type Stripping と相性が悪い 53 → 新しい流れと噛み合わず   今後負債になる運命
  29. © teamLab Inc. なぜ、さよならを告げるべきなのか - 生成コードとバンドルに不利 - TypeScript の現在の方針と相性が悪い -

    標準化にも壁がある - Node.js の Type Stripping と相性が悪い 54 → 新しい流れと噛み合わず   今後負債になる運命 JS enum 実現するかも...?
  30. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 57 const obj =

    { Open: 1 } as const 読み取り専用オブジェクト型として扱う
  31. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 60 const obj =

    { Open: 1 } as const obj.Open = 2; // ^ Cannot assign to 'Open' because it is a read-only property.(2540)
  32. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 62 const obj =

    { Open: 1 } as const readonly Open: 1 修飾: これは読み取り専用
  33. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 63 const Status =

    { // ^ const Status: { // readonly Open: 0; // readonly Closed: 1; // } Open: 0, Closed: 1, } as const; const CurrentStatus = Status.Closed; // ^ const CurrentStatus: 1
  34. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 64 type Obj =

    typeof obj[keyof typeof obj]; 読み取り専用 Object から 型だけを取り出す
  35. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 65 type Obj =

    typeof obj[keyof typeof obj]; obj のプロパティ名(key)を取り出す → { Open: 1 } → “Open”
  36. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 66 type Obj =

    typeof obj[keyof typeof obj]; obj の key に対応する value を取り出す → { Open: 1 } → “1”
  37. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 67 type Obj =

    typeof obj[keyof typeof obj]; obj の value の Union 型になる → { Open: 1 } なら Obj = “1”
  38. © teamLab Inc. TypeScript enum みたいな実装をしたいとき 68 type ObjKey =

    keyof typeof Status // ^ type ObjKey = "Open" | "Closed" type Obj = typeof Status[keyof typeof Status]; // ^ type Obj = 0 | 1