Module Augmentation
In this page:
Understanding Module Augmentation
Module augmentation lets you reopen an existing module's exported types from your own code and add new members to them, which is useful when a library's types are missing something you need without forking the library itself.
Example: Understanding Module Augmentation
// Reopening an existing module's types to add a member:
declare module "existing-lib" {
export interface Config {
customOption?: boolean;
}
}
console.log("Module augmentation adds to a library's existing types");
Augmenting an Interface
Augmenting an interface that a module exports means declaring the same interface name inside a declare module block; TypeScript merges your additional properties into the original interface rather than replacing it.
Example: Augmenting an Interface
declare module "existing-lib" {
interface Config {
timeout: number;
}
}
// TypeScript merges this into the original Config interface.
console.log("Augmented interface merges rather than replaces");
Augmenting a Class API
Augmenting a class's exported API works the same way as an interface — you add new method or property signatures inside the module declaration, and TypeScript treats the class as having always had them.
Example: Augmenting a Class API
declare module "existing-lib" {
interface Client {
retryCount: number;
}
}
console.log("Class API augmented with an additional property");
Runtime Implementation
Module augmentation only changes what TypeScript believes exists — it adds zero runtime behavior, so any property or method you augment onto a type must already actually exist at runtime, or calling it will fail.
Example: Runtime Implementation
// Augmentation only changes what TypeScript believes exists.
// The property must ALREADY exist at runtime or calling it fails:
declare module "existing-lib" {
interface Client {
debugMode: boolean;
}
}
console.log("Augmentation adds zero runtime behavior on its own");
When to Use Module Augmentation
Reach for module augmentation when a third-party library's published types are incomplete or slightly wrong for your use case; for everything else, extending or wrapping the library in your own code is usually a safer, less fragile choice.
Example: When to Use Module Augmentation
// Use when a library's published types are incomplete or wrong.
// For everything else, wrapping the library in your own code is safer.
declare module "existing-lib" {
interface Config {
experimentalFlag?: boolean;
}
}
console.log("Reach for augmentation only when types are genuinely incomplete");
Chapter Quiz — Complete all 5 topics to unlock
0/5 topics done
Complete these topics first: