Microsoft/TypeScript

`export { _void as void }` leads to exporting duplicate identifiers

Open

#62081 opened on Jul 16, 2025

View on GitHub
 (1 comment) (0 reactions) (0 assignees)TypeScript (48,455 stars) (6,726 forks)batch import
BugDomain: Declaration EmitHelp Wanted

Description

🔎 Search Terms

export void export reserved export null

🕗 Version & Regression Information

  • Reproducible since typescript v4. In older releases, it doesn't export anything. I also tried the latest dev release (5.9.0-dev.20250716)
  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about exports

⏯ Playground Link

Playground (important: lang:javascript)

💻 Code

Using the following tsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "lib": ["esnext"],
    "module": "esnext",
    "allowJs": true,
    "checkJs": true,
    "declaration": true,
    "declarationMap": true,
    "outDir": "./dist",
    "emitDeclarationOnly": true,
    "strict": true,
    "noImplicitAny": true,
    "moduleResolution": "bundler"
  }
}

I compile declaration files for this code ${project}/schema.js (only happens when compiling javascript):

const _null = {}
const $void = {}

export { _null as null, $void as void }

🙁 Actual behavior

The produced declaration file schema.d.ts is erroneous. It has duplicate identifiers:

declare const _null: {};
declare const $void: {};
export { _null as null, _null as null, $void as void, _void as void };

🙂 Expected behavior

No duplicate identifiers:

declare const _null: {};
declare const $void: {};
export { _null as null, $void as void };

Additional information about the issue

For any reserved keyword, tsc always exports _{reserved} as {reserved}, whenever {reserved} is exported. Even though the variable _{reserved} does not exist.

It is only reproducible when compiling javascript.

Contributor guide