Skip to content

Export TypeScript namespace when ExportTypes is enabled - #5402

Open
mario-ruiz22 wants to merge 2 commits into
RicoSuter:masterfrom
mario-ruiz22:fix/typescript-namespace-missing-export
Open

mario-ruiz22 wants to merge 2 commits into
RicoSuter:masterfrom
mario-ruiz22:fix/typescript-namespace-missing-export

Conversation

@mario-ruiz22

@mario-ruiz22 mario-ruiz22 commented Sep 10, 2026 •

Copy link
Copy Markdown

When generating TypeScript with /namespace:, the generated namespace X { ... } block never gets the export keyword, even when ExportTypes is true. That means the namespace can't be imported by consumers at all.

The module branch in File.liquid already gates its export keyword on ExportTypes. The namespace branch right below it never did. This PR brings namespace in line with module.

Why

ExportTypes is the existing setting for controlling whether generated declarations get exported. Every other top-level declaration in File.liquid (classes, interfaces, the module block) already respects it. namespace was the one place this got missed. Gating on ExportTypes instead of always exporting keeps the option open for consumers who load the output as a plain script instead of a module.

Why not just use /moduleName: instead, since it already exports? Because it emits the module keyword, which TypeScript 6.0+ hard-deprecates and errors on (TS1540). So moduleName isn't a real alternative for anyone on TypeScript 6.0+.

Breaking changes

None functionally, but output changes for most /namespace: users: ExportTypes defaults to true, so the generated namespace block will now include export by default (it never did before, regardless of ExportTypes). If you explicitly set /exportTypes:false, nothing changes.

Verification

  • Relevant builds and tests run, with results recorded. Added a theory test in CodeGenerationTests.cs, When_namespace_is_set_then_namespace_is_exported_based_on_export_types, covering ExportTypes true and false. Both cases pass and compile the generated output via TypeScriptCompiler.AssertCompile.
  • Relevant snapshot or output diffs reviewed. None of the existing snapshots use /namespace:, so none are affected. The actual output diff (namespace X { vs export namespace X {) is checked directly in the new test's assertions, and reviewed again by hand in the manual real-spec verification below.
  • Manually verified against a real, production OpenAPI spec: built NSwag.ConsoleCore from this branch and ran openapi2tsclient with /namespace: against a real internal spec. Output now compiles and imports correctly, where it previously failed with TS2459.
  • Documentation and samples updated. Not needed for this change. See the TypeScriptGeneratorSettings wiki page for the related settings.

@nycdotnet

Copy link
Copy Markdown

We've tested this change internally and it has unblocked our conversion to Angular 22 which uses TypeScript 6. Thanks for considering it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants