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.
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.
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 failTypeScript 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.
error TS5023: Unknown compiler option 'files'.
How to fix "Unknown compiler option" in TypeScript
Object literal may only specify known properties, and 'name' does not exist in type 'T'. ts(2353)
How to fix 'Object literal may only specify known properties' in TypeScript
Cannot find name 'process'. Do you need to install type definitions for node? Try `npm i --save-dev @types/node` and then add 'node' to the types field in your tsconfig.
How to fix "Cannot find name 'process'" in TypeScript
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript