Namespace is a mechanism for organizing code that emerged in the pre-ES6 era to group logically related entities together. It helps structure large projects by grouping classes, functions, interfaces, and types within a single namespace to avoid name conflicts and make the code more readable.
Historical context: Before the advent of JavaScript ES6 standards, developers used IIFEs, objects, and namespaces to simulate modularity. TypeScript introduced the namespace keyword (previously internal module) for grouping code.
Problem: Modern modules (ES6 Module) have become the standard, and both approaches (namespace and module) exist in parallel, which causes confusion in architectural design — when is it better to use a namespace, and when a module?
Solution: Namespaces are still useful for grouping utility functions and types in pure TypeScript projects (for example, when generating single JS files with outFile). To separate code across files, especially when working with npm and modern bundlers, it is more appropriate to use modules. Namespaces are often used in internal libraries, type declarations, and situations where structuring within a single file or in old code is necessary.
Example code:
namespace MyMath { export function add(a: number, b: number) { return a + b; } } console.log(MyMath.add(2, 3)); // 5
Key features:
If you merge namespaces from different files, will it be one namespace or several?
TypeScript performs declaration merging — when names match, different parts of the namespace are merged into one if correctly connected and in the same scope.
// mathA.ts namespace MathUtil { export function sum(a: number, b: number) { return a + b; } } // mathB.ts namespace MathUtil { export function mul(a: number, b: number) { return a * b; } } // After compilation, MathUtil contains both methods
Can you use import/require for namespace like for a module?
No, namespaces do not have default export/named export; they cannot be imported using the standard ES6 syntax. Namespace is a purely TypeScript concept that does not transpile to JavaScript modules.
Can you import values from a namespace into another file via import?
No, accessing a namespace from other files requires using a reference (/// <reference path="..." />) or compiling with outFile; importing via import is impossible.
In an old project, the logic was divided into dozens of namespaces, with the same names appearing in several files, which sometimes led to unexpected merging or conflicts. Transitioning to a modular architecture made code migration very labor-intensive.
Pros:
Cons:
In a large library, an API was declared using namespace declarations in a single file index.d.ts, unifying all types and interfaces without implementation code. This enabled rapid typing for library consumers and simplified updating contracts between teams.
Pros:
Cons: