oxc-project/oxc · warning · OxcDiagnostic

Namespaces exporting non-const are not supported by Oxc. Cha

Error message

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

What it means

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.

Source

Thrown at crates/oxc_transformer/src/typescript/diagnostics.rs:31

}

#[cold]
pub fn export_assignment_cannot_bed_used_in_esm(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Export assignment cannot be used when targeting ECMAScript modules.")
        .with_help("Consider using 'export default' or another module format instead.")
        .with_label(span)
        .with_error_code("TS", "1203")
}

#[cold]
pub fn ambient_module_nested(span: Span) -> OxcDiagnostic {
    OxcDiagnostic::warn("Ambient modules cannot be nested in other modules or namespaces.")
        .with_label(span)
}

#[cold]
pub fn namespace_exporting_non_const(span: Span) -> OxcDiagnostic {
    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")
        .with_label(span)
}

#[cold]
pub fn namespace_not_supported(span: Span) -> OxcDiagnostic {
    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")
        .with_label(span)
}

View on GitHub (pinned to e1e7af627c)

Solutions

  1. 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++`
  2. Replace the namespace with an ES module: move members to a `.ts` module with named exports, which supports mutable exports via re-export patterns
  3. If the variable is never rebound, `const` is a drop-in change and the warning disappears

Example fix

// before
namespace Counter {
  export let current = 0;
  export function next() { current += 1; return current; }
}

// after
namespace Counter {
  export const state = { current: 0 };
  export function next() { state.current += 1; return state.current; }
}
Defensive patterns

Strategy: validation

Validate before calling

// Flag non-const exports inside namespaces before running oxc
function hasNonConstNamespaceExport(src: string): boolean {
  return /(?:^|\n)\s*export\s+(?:let|var)\s+\w+/.test(src);
}
// ground it further: only warn-prone when a namespace/module block is present
const needsFix = /(?:^|\n)\s*(?:export\s+)?(?:namespace|module)\s+\w+\s*\{/.test(src) && hasNonConstNamespaceExport(src);

Type guard

// Guard the code style itself
function assertConstOnlyNamespaceExports(ast: TsNode[]) {
  for (const n of ast.filter(isInsideNamespace)) {
    if (n.kind === 'VariableStatement' && n.declarationList.kind !== 'const') {
      throw new Error('namespace exports must be const (oxc/babel limitation)');
    }
  }
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/e53db9e4f903af43. Report an issue: GitHub.