Skip to content

declare const enum values not inlined - ReferenceError at runtime #4394

@jrieken

Description

@jrieken

Summary

esbuild does not inline declare const enum member values at usage sites. TypeScript does — it replaces usages like Foo.A with the literal value 1. esbuild leaves the enum identifier as-is, causing a ReferenceError at runtime since declare means no enum object is emitted.

Repro

// input.ts
export declare const enum Foo { A = 1, B = 2 }

export function test() {
  console.log(Foo.A);
}

Expected output (what tsc produces):

export function test() {
  console.log(1 /* Foo.A */);
}

Actual esbuild output:

export function test() {
  console.log(Foo.A); // ReferenceError: Foo is not defined
}

Note: esbuild correctly inlines const enum (without declare). The bug is specific to the declare modifier. Both const enum and declare const enum should have the same runtime semantics — values inlined, no enum object emitted.

esbuild playground link

https://esbuild.github.io/try/#YgAwLjI3LjAALS10YXJnZXQ6ZXMyMDI0AGUAZW50cnkudHMAZXhwb3J0IGRlY2xhcmUgY29uc3QgZW51bSBGb28geyBBID0gMSwgQiA9IDIgfQoKZXhwb3J0IGZ1bmN0aW9uIHRlc3QoKSB7CiAgY29uc29sZS5sb2coRm9vLkEpOwp9

Impact

This causes runtime crashes in VS Code (microsoft/vscode#295046). We are working around it by removing declare from our const enum declarations.

Environment

  • esbuild 0.27.0
  • Using esbuild.transform() with loader: 'ts', target: 'es2024'
  • Also reproducible with esbuild.build()

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions