Module Augmentation allows you to extend or modify existing modules — useful when:
You want to add custom typings to a third-party library.
You need to extend interfaces, add functions, or override types of an existing module (like a package from
node_modules).
🧠 Core Idea
Module augmentation uses the declare module syntax to re-open a module and add types or members to it.
📘 Basic Example
Original module (e.g. from my-lib):
// node_modules/my-lib/index.d.ts
declare module "my-lib" {
export interface User {
name: string;
}
}➕ Augmenting the module:
// types/my-lib-augmentation.d.ts
import "my-lib";
declare module "my-lib" {
interface User {
age: number; // ⬅️ Added property
}
export function getUserAge(user: User): number; // ⬅️ New function
}Now you can use the age property and getUserAge() in your code, and TypeScript will recognize them.
🧩 Real Use Case: Extending Express Request
// types/express/index.d.ts
import "express";
declare module "express-serve-static-core" {
interface Request {
user?: { id: string; role: string };
}
}Now in your app:
app.get("/profile", (req, res) => {
console.log(req.user?.id); // ✅ No TypeScript error
});⚠️ Best Practices
Always import the original module first (e.g.
import "express";) to ensure the augmentation merges.Put all augmentation files in a
types/folder and include it intsconfig.json:
{
"compilerOptions": {
"typeRoots": ["./types", "./node_modules/@types"]
}
}✅ When to Use
Use Case | Augmentation Needed? |
|---|---|
Add fields to existing types (like | ✅ Yes |
Extend a third-party library's exported interface | ✅ Yes |
Add global types or custom modules | ❌ Use |