Skip to content

Proposal: Add \enum const\ modifier to auto-generate union types for constant objects #63657

Description

@yxdtg

A type-only, fully erasable modifier with zero runtime overhead.

enum const Status = {
    Success: "success",
    Failure: "failure",
    Pending: "pending",
};

Desugared TypeScript Equivalent

The compiler desugars this internally to standard TS. No manual boilerplate required.

The const value and type share the same name, leveraging TypeScript's separate value/type namespaces.

const Status = {
    Success: "success",
    Failure: "failure",
    Pending: "pending",
} as const;
type Status = (typeof Status)[keyof typeof Status];

Compiled JavaScript Output

The enum modifier is stripped entirely. Output is a native JS object with no extra generated code.

const Status = {
    Success: "success",
    Failure: "failure",
    Pending: "pending",
};

✅ Viability Checklist

⭐ Suggestion

Compatibility

  • Fully backward compatible: this is a new additive syntax, no breaking changes to existing code
  • Compatible with isolatedDeclarations and isolatedModules
  • Aligns with erasableSyntaxOnly: no runtime code is generated
  • No conflict with existing const enum, as the keyword order and semantics are clearly distinct

📃 Motivating Example

Current approaches for type-safe constant collections in TypeScript all have notable tradeoffs:

  1. Standard enum generates extra runtime code
    It produces bidirectional mapping IIFE in JavaScript output, adding bundle overhead. It conflicts with the erasableSyntaxOnly principle and cannot be extended via object spread.
  2. const enum has severe compatibility limits
    Values are inlined at compile time and break across file/package boundaries. It is incompatible with isolatedModules and isolatedDeclarations, making it unusable for libraries and monorepos.
  3. as const objects require heavy boilerplate
    The de facto standard pattern forces developers to manually derive union types with type T = typeof Obj[keyof typeof Obj]. This becomes even more verbose under isolatedDeclarations, where every cross-file usage requires explicit typeof annotations to avoid cross-file type inference.

This proposal introduces a lightweight, type-only erasable modifier that solves all the above issues: it retains native JavaScript object semantics, produces zero runtime overhead, and is natively compatible with single-file compilation architectures.

💻 Use Cases

  • Shared status codes, state constants and configuration values in application code
  • Enum-like public APIs in component libraries and SDKs
  • Cross-package constant definitions in monorepos, where const enum cannot be used
  • Constant objects that need to be extended, merged or spread while preserving type safety

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions