In TypeScript, namespaces provide a way to group related functionalities together, helping to avoid naming conflicts in large projects. However, with the introduction of ES6 modules, namespaces have become less commonly used. Despite that, they still serve a purpose in legacy applications, global libraries, and non-module environments.
1οΈβ£ What is a Namespace?
A namespace in TypeScript is a container for grouping related variables, classes, interfaces, and functions under a single name. This helps prevent name collisions, especially in large applications.
When to Use Namespaces?
β
If you’re working on a global library (e.g., a utility library used in browsers).
β
If you’re dealing with legacy projects that don’t support ES6 modules.
β
If you’re writing TypeScript without module bundlers (like Webpack, Rollup).
However, if you’re building modern applications, ES6 modules (import/export
) are the preferred approach.
2οΈβ£ How to Define a Namespace?
We use the namespace
keyword to define a namespace.
Example: Basic Namespace Usage
namespace MathOperations {
export function add(a: number, b: number): number {
return a + b;
}
export function subtract(a: number, b: number): number {
return a - b;
}
}
// Using the namespace
console.log(MathOperations.add(5, 3)); // 8
console.log(MathOperations.subtract(10, 4)); // 6
πΉ Explanation:
MathOperations
is a namespace that groups related functions.- We use
export
inside the namespace to make functions accessible outside. - To access functions, we use
MathOperations.add()
instead of calling them directly.
3οΈβ£ Nested Namespaces
You can create namespaces inside namespaces to organize large applications.
Example: Nested Namespaces
namespace MathOperations {
export namespace Advanced {
export function square(n: number): number {
return n * n;
}
}
}
console.log(MathOperations.Advanced.square(5)); // 25
πΉ Explanation:
Advanced
is a sub-namespace insideMathOperations
.- To access
square()
, we useMathOperations.Advanced.square()
.
4οΈβ£ Namespace with Interfaces & Classes
A namespace can also define interfaces and classes.
Example: Using Interfaces and Classes in a Namespace
namespace Vehicles {
export interface Vehicle {
name: string;
speed: number;
drive(): void;
}
export class Car implements Vehicle {
constructor(public name: string, public speed: number) {}
drive() {
console.log(`${this.name} is driving at ${this.speed} km/h`);
}
}
}
const myCar = new Vehicles.Car("Tesla", 120);
myCar.drive(); // Tesla is driving at 120 km/h
πΉ Explanation:
Vehicle
is an interface inside theVehicles
namespace.Car
is a class inside the namespace and implementsVehicle
.- The
export
keyword makesVehicle
andCar
accessible outside the namespace.
5οΈβ£ Merging Namespaces
You can define a namespace in multiple files or multiple locations in the same file, and TypeScript will merge them.
Example: Namespace Merging
namespace Library {
export class Book {
constructor(public title: string) {}
}
}
// Another part of the code (same namespace)
namespace Library {
export function getBookInfo(book: Book) {
console.log(`Book Title: ${book.title}`);
}
}
const myBook = new Library.Book("TypeScript Guide");
Library.getBookInfo(myBook);
πΉ Explanation:
- The
Library
namespace is defined in multiple places, but TypeScript merges them into a single namespace. - This is useful for large applications where functionalities are split across files.
6οΈβ£ Using Namespaces in Multiple Files
If your namespaces are in separate files, you need to reference them correctly.
File: math.ts
namespace MathOperations {
export function multiply(a: number, b: number): number {
return a * b;
}
}
File: main.ts
/// <reference path="math.ts" />
console.log(MathOperations.multiply(4, 5)); // 20
πΉ Explanation:
/// <reference path="math.ts" />
tells TypeScript to includemath.ts
in compilation.- This is only needed in non-module environments (like older TypeScript projects).
7οΈβ£ Namespace vs. Class vs. ES6 Modules
Feature | Namespace | Class | ES6 Modules |
---|---|---|---|
Purpose | Group related code | Blueprint for objects | Modular code organization |
Encapsulation | β Yes | β Yes | β Yes |
Instance Creation | β No | β
Yes (new ) |
β No |
File Organization | β Good for large codebases | β Good for OOP | β Preferred for modern apps |
Importing/Exporting | β
Uses export inside namespaces |
β
Uses export class |
β
Uses import/export |
Recommended in Modern Apps? | β No | β Yes | β Yes |
π Conclusion:
- β Use classes when you need to create objects and follow OOP principles.
- β
Use ES6 modules (
import/export
) for modern applications. - β Use namespaces only for global libraries or legacy projects.
8οΈβ£ What Happens if You’re Creating a Library?
If you’re building a TypeScript library, the best choice depends on the environment:
πΉ Use ES6 Modules (import/export
) for Modern Libraries
- Better tree shaking (reduces bundle size).
- Works well with modern module bundlers (Webpack, Rollup).
- Easy to manage using
npm
.
Example: Library with ES6 Modules
// math.ts
export function add(a: number, b: number) {
return a + b;
}
// main.ts
import { add } from "./math";
console.log(add(5, 3)); // 8
πΉ Use Namespaces for Global Libraries (Browser-based)
- Useful for libraries that don’t use module bundlers.
- Can be included in a
<script>
tag.
Example: Library with Namespaces
namespace MathLib {
export function add(a: number, b: number) {
return a + b;
}
}
<script src="math.js"></script>
<script>
console.log(MathLib.add(5, 3)); // 8
</script>
Which One to Use?
β
Use ES6 modules if you’re publishing a library via npm
.
β
Use namespaces if you’re building a browser-based global library.
9οΈβ£ Summary – Key Takeaways
β
Namespaces help group related functionalities in TypeScript.
β
Use export
inside a namespace to make things accessible.
β
Nested namespaces allow better code organization.
β
You can define interfaces, classes, and functions inside a namespace.
β
Modern projects prefer ES6 modules (import/export
) over namespaces.
β
Use namespaces only for legacy projects or global browser libraries.
π Final Advice: If you’re starting a new project or creating a modern library, stick with ES6 modules instead of namespaces.