TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

Redesign `(const) enum` and `namespace` emit for better treeshaking

Open Septh opened this issue 2 months ago • 0 comments

🔍 Search Terms

enum emit in:title enum treeshaking enum esbuild

✅ Viability Checklist

  • [x] This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • [x] This wouldn't change the runtime behavior of existing JavaScript code
  • [x] This could be implemented without emitting different JS based on the types of the expressions
  • [x] This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, new syntax sugar for JS, etc.)
  • [x] This isn't a request to add a new utility type: https://github.com/microsoft/TypeScript/wiki/No-New-Utility-Types
  • [x] This feature would agree with the rest of our Design Goals: https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

⭐ Suggestion

Adopt esbuild-like code generation for enums, preserved const enums and namespaces to allow for better treeshaking by bundlers.

📃 Motivating Example

Not all bundlers generate their own JS from TS. esbuild does, but @rollup/plugin-typescript, for instance, relies on the genuine tsc compiler.

Given the following enum:

export enum X { a, b=10, c }

tsc actually emits this:

export var X;
(function (X) {
  X[X["a"] = 0] = "a";
  X[X["b"] = 10] = "b";
  X[X["c"] = 11] = "c";
})(X || (X = {}));

which unfortunately does not treeshake well. If you import only one enum from a file that defines many, all of them end up in the bundle. Not cool.

To mitigate this, esbuild (and probably other transpilers?) emits this kind of code instead:

export var X = /* @__PURE__ */ ((X) => {
  X[X["a"] = 0] = "a";
  X[X["b"] = 10] = "b";
  X[X["c"] = 11] = "c";
  return X;
})(X || {});

Not using an IIFE and adding the __PURE__ annotation make this code 100% treeshakable.

Unless I'm missing something, I don't think tsc embracing a similar approach would break any existing code.

💻 Use Cases

  1. What do you want to use this for?

Efficient treeshaking.

  1. What shortcomings exist with current approaches?

See above.

  1. What workarounds are you using in the meantime?

Using my own rollup plugin that transforms all emitted enums before treeshaking.

Septh avatar Dec 11 '25 16:12 Septh