How to fix Namespace cannot be declared in non-module context in TypeScript
This TypeScript error occurs when trying to declare a namespace in a file that TypeScript doesn't recognize as a module. Namespaces require module context, which can be enabled by adding export statements, using ES modules, or configuring TypeScript appropriately.
Quick fix
Fixes Namespace cannot be declared in non-module context
// Add this to make the file a module
export {};
// Now you can declare namespaces
namespace MyNamespace {
export function doSomething() {
console.log("Hello from namespace");
}
}- Add an export statement to make the file a module
- Convert to ES modules by adding import/export
- Check your tsconfig.json module setting
- Consider using modules instead of namespaces
// Add this to make the file a moduleexport {};// Now you can declare namespacesnamespace MyNamespace {export function doSomething() {console.log("Hello from namespace");}}Namespace cannot be declared in non-module context
What this error means
TypeScript namespaces are a way to organize code and prevent naming conflicts by grouping related functionality. However, namespaces can only be declared in module contexts - files that TypeScript recognizes as modules. A file becomes a module when it contains at least one import or export statement, or when using ES module syntax. This error prevents namespace declarations in script files (non-modules) where all code is in the global scope.
Typical symptoms
- TypeScript compiler throws error: "Namespace cannot be declared in non-module context"
- Build process fails when trying to compile TypeScript files with namespace declarations
- IDE shows red squiggly lines under namespace declarations in certain files
- Code works in JavaScript but fails when converted to TypeScript with namespace usage
Common causes
- Missing import/export statements in the file (makes it a script, not a module)
- Using namespace syntax in a .ts file without any module indicators
- Incorrect TypeScript configuration (module setting in tsconfig.json)
- Trying to use namespaces in files meant to be global scripts
- Mixing CommonJS and ES module syntax incorrectly
How to fix "Namespace cannot be declared in non-module context"
The simplest fix is to add any export statement to your file. This tells TypeScript the file is a module, allowing namespace declarations.
// Add this to make the file a module
export {};
// Now you can declare namespaces
namespace MyNamespace {
export function doSomething() {
console.log("Hello from namespace");
}
}If you're using ES modules, ensure you have proper import/export statements:
// Import something to make it a module
import { something } from "./other-module";
// Or export something
export const myConstant = 42;
namespace MyNamespace {
export function doSomething() {
console.log("Working with", something);
}
}Ensure your TypeScript configuration is set up correctly for modules:
{
"compilerOptions": {
"module": "commonjs", // or "es2015", "esnext", etc.
"target": "es2015",
// Other options...
}
}Common module settings:
- "commonjs": For Node.js environments
- "es2015" / "esnext": For modern JavaScript
- "amd": For RequireJS/AMD modules
- "umd": Universal module definition
Modern TypeScript/JavaScript favors ES modules over namespaces. Consider converting namespace code to module exports:
// Instead of:
namespace Utilities {
export function formatDate(date: Date): string {
return date.toISOString();
}
}
// Use:
export function formatDate(date: Date): string {
return date.toISOString();
}
// Or group in an object:
export const Utilities = {
formatDate(date: Date): string {
return date.toISOString();
}
};If you need to augment global types in a non-module context, use declare global instead of namespaces:
// In a .d.ts file or file without imports/exports
declare global {
interface Window {
myCustomProperty: string;
}
}
// This works in non-module contexts
// while namespaces would failAdvanced notes
TypeScript has two file modes: scripts and modules. Scripts are files without imports/exports where all code is in global scope. Modules are files with imports/exports that have their own scope. Namespaces are only allowed in modules because they create their own scope. The isolatedModules compiler flag can affect this behavior - when enabled, all files must be modules. For legacy codebases, you might need to add export {} to many files to make them modules. Note that namespaces are somewhat deprecated in favor of ES modules, but are still useful for organizing large codebases or creating declaration files.
Frequently asked questions
- What does "Namespace cannot be declared in non-module context" mean?
- TypeScript namespaces are a way to organize code and prevent naming conflicts by grouping related functionality. However, namespaces can only be declared in module contexts - files that TypeScript recognizes as modules. A file becomes a module when it contains at least one import or export statement, or when using ES module syntax.
- How do I fix "Namespace cannot be declared in non-module context"?
- This TypeScript error occurs when trying to declare a namespace in a file that TypeScript doesn't recognize as a module. Namespaces require module context, which can be enabled by adding export statements, using ES modules, or configuring TypeScript appropriately.
- What causes "Namespace cannot be declared in non-module context"?
- Missing import/export statements in the file (makes it a script, not a module) Using namespace syntax in a .ts file without any module indicators Incorrect TypeScript configuration (module setting in tsconfig.json)
- Is the "Namespace cannot be declared in non-module context" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐TypeScript Official Documentation
- ๐Typescriptlang.org - namespaces.html(Official Docs)
- ๐Typescriptlang.org - isolatedModules.html(Official Docs)
- ๐ฌ
- ๐Github.com - 14351(GitHub)
- ๐Typescriptlang.org - modules.html(Official Docs)