{"record":{"id":"e53db9e4f903af43","repo":"oxc-project/oxc","slug":"namespaces-exporting-non-const-are-not-supported-b","errorCode":null,"errorMessage":"Namespaces exporting non-const are not supported by Oxc. Change to const or see: https://oxc.rs/docs/guide/usage/transformer/typescript.html#partial-namespace-support","messagePattern":"Namespaces exporting non-const are not supported by Oxc\\. Change to const or see: https://oxc\\.rs/docs/guide/usage/transformer/typescript\\.html#partial-namespace-support","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_transformer/src/typescript/diagnostics.rs","lineNumber":31,"sourceCode":"}\n\n#[cold]\npub fn export_assignment_cannot_bed_used_in_esm(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Export assignment cannot be used when targeting ECMAScript modules.\")\n        .with_help(\"Consider using 'export default' or another module format instead.\")\n        .with_label(span)\n        .with_error_code(\"TS\", \"1203\")\n}\n\n#[cold]\npub fn ambient_module_nested(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Ambient modules cannot be nested in other modules or namespaces.\")\n        .with_label(span)\n}\n\n#[cold]\npub fn namespace_exporting_non_const(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Namespaces exporting non-const are not supported by Oxc. Change to const or see: https://oxc.rs/docs/guide/usage/transformer/typescript.html#partial-namespace-support\")\n        .with_label(span)\n}\n\n#[cold]\npub fn namespace_not_supported(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Namespace not marked type-only declare are disabled. To enable and review caveats see: https://oxc.rs/docs/guide/usage/transformer/typescript.html#partial-namespace-support\")\n        .with_label(span)\n}\n","sourceCodeStart":13,"sourceCodeEnd":40,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_transformer/src/typescript/diagnostics.rs#L13-L40","documentation":"While flattening a TypeScript namespace into an IIFE-style `let` + function wrapper, Oxc's namespace transform only supports exporting `const` variable declarations from a namespace. When a `VariableDeclaration` inside the namespace body has kind `let` or `var` (namespace.rs:256-261), each declarator gets the `namespace_exporting_non_const` warning (typescript/diagnostics.rs:31) — mirroring @babel/plugin-transform-typescript's limitation — because mutable namespace bindings cannot be represented correctly in the lowered output.","triggerScenarios":"Transforming TypeScript like `namespace Counter { export let current = 0; }` or `namespace State { export var retries = 3; }` with namespaces enabled (`allowNamespaces: true`, which is the default at typescript/options.rs:117). The check is `!var_decl.kind.is_const()` inside handle_nested's body walk, so only non-const variable declarations warn; functions, classes, enums, and const declarations inside namespaces are fine.","commonSituations":"Porting older TS codebases (early TypeScript encouraged namespaces with mutable `export var` state, e.g. module-pattern singletons); game/REPL-style code holding mutable state in namespaces; refactoring `module App { export let mode = 'dev' }` patterns from pre-ES2015 code into a modern oxc-based build; following old tutorials that use `export var` inside namespaces.","solutions":["Change `let`/`var` to `const` inside the namespace and mutate the object's properties instead of rebinding: `export const state = { count: 0 }` then `state.count++`","Replace the namespace with an ES module: move members to a `.ts` module with named exports, which supports mutable exports via re-export patterns","If the variable is never rebound, `const` is a drop-in change and the warning disappears"],"exampleFix":"// before\nnamespace Counter {\n  export let current = 0;\n  export function next() { current += 1; return current; }\n}\n\n// after\nnamespace Counter {\n  export const state = { current: 0 };\n  export function next() { state.current += 1; return state.current; }\n}","handlingStrategy":"validation","validationCode":"// Flag non-const exports inside namespaces before running oxc\nfunction hasNonConstNamespaceExport(src: string): boolean {\n  return /(?:^|\\n)\\s*export\\s+(?:let|var)\\s+\\w+/.test(src);\n}\n// ground it further: only warn-prone when a namespace/module block is present\nconst needsFix = /(?:^|\\n)\\s*(?:export\\s+)?(?:namespace|module)\\s+\\w+\\s*\\{/.test(src) && hasNonConstNamespaceExport(src);","typeGuard":"// Guard the code style itself\nfunction assertConstOnlyNamespaceExports(ast: TsNode[]) {\n  for (const n of ast.filter(isInsideNamespace)) {\n    if (n.kind === 'VariableStatement' && n.declarationList.kind !== 'const') {\n      throw new Error('namespace exports must be const (oxc/babel limitation)');\n    }\n  }\n}","tryCatchPattern":null,"preventionTips":["Use `export const state = {...}` plus property mutation instead of `export let/var` rebinding inside namespaces","Migrate namespaces to ES modules when mutable bindings are genuinely needed","Add a lint rule banning `export let`/`export var` inside namespace blocks so the pattern dies at review time"],"tags":["oxc","typescript","transformer","namespaces","babel-compat"],"backgroundTag":"typescript-namespace-unsupported","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}