This TypeScript error occurs when you attempt to use module augmentation syntax in a file that TypeScript doesn't recognize as a proper module. Module augmentation requires the file to be treated as a module, which happens when it contains import or export statements.
In TypeScript, module augmentation allows you to extend type definitions of existing modules using the declare module syntax. However, TypeScript enforces a strict rule: a file must be recognized as a module (by containing import/export statements) for module augmentation to work within it. The error "Cannot augment module 'X' outside of its own definition" means you're trying to augment a module in a context where TypeScript doesn't recognize your current file as a proper module. This typically happens in two scenarios: 1. Your .d.ts file is treated as a script (global scope) rather than a module 2. Your file lacks the necessary import/export statements to be recognized as a module Without an explicit module context, TypeScript treats declarations as global, which conflicts with the intent of declare module statements that should extend specific named modules.
The simplest fix is to add an import statement at the beginning of your file. This ensures TypeScript treats your file as a module rather than a global script:
// ❌ Wrong - no imports, treated as global script
declare module 'my-library' {
export interface MyType {
customProp: string;
}
}
// ✅ Correct - import makes it a module
import 'my-library'; // Import the module first
declare module 'my-library' {
export interface MyType {
customProp: string;
}
}The import statement doesn't need to import anything specific—it just signals to TypeScript that this is a module file, enabling module augmentation syntax.
If importing the module doesn't make sense for your use case, add an empty export to establish module context:
// ✅ Correct - export makes it a module
declare module 'jquery' {
interface JQuery {
customMethod(): void;
}
}
export {}; // Makes this file a moduleThis empty export statement tells TypeScript "treat this as a module" without actually exporting anything. It's a common pattern in .d.ts files where you only want to augment types.
Ensure your augmentation file is included in your tsconfig.json:
{
"compilerOptions": {
"declaration": true,
"declarationDir": "./types"
},
"include": [
"src/**/*",
"types/**/*.d.ts"
]
}If your augmentation file is in a subdirectory, make sure it's explicitly included in the "include" array. TypeScript must be able to find and process the file.
Verify the module name in your declare module statement matches the actual module package name:
// If the package is named 'lodash'
declare module 'lodash' {
export interface LoDashStatic {
customUtility(): string;
}
}
// NOT 'lodash/lib' or '_' or other variations
// Use the exact package name from node_modulesCheck your package.json or node_modules to confirm the exact module name. Using incorrect module names will cause augmentation to fail.
If you're actually trying to augment global types (not module-specific types), use declare global syntax instead:
// ❌ Wrong approach for global augmentation
declare module 'global' {
interface Window {
customProp: string;
}
}
// ✅ Correct approach for global types
declare global {
interface Window {
customProp: string;
}
}
export {}; // Make it a moduledeclare global applies to the global namespace (window, process, etc.), while declare module augments specific named modules.
Create the augmentation in a .d.ts file with proper module context:
// ✅ Good structure for types/express-augmentation.d.ts
import 'express'; // or export {}
declare module 'express' {
interface Request {
userId?: string;
}
}Include it in tsconfig.json:
{
"include": [
"src/**/*",
"types/**/*.d.ts"
]
}This ensures the file is recognized as a module and properly processed by TypeScript.
If you're using legacy triple-slash directives, ensure you still have module context:
// ❌ Triple-slash without module context
/// <reference path="./my-types.d.ts" />
declare module 'my-library' {
export interface MyType {}
}
// ✅ With proper module context
/// <reference path="./my-types.d.ts" />
import 'my-library';
declare module 'my-library' {
export interface MyType {}
}Triple-slash directives don't establish module context by themselves. You still need an import or export statement.
TypeScript distinguishes between script scope and module scope. A file is treated as a module when it contains top-level import or export statements. Files without these are treated as scripts, where declarations are global.
For module augmentation to work, TypeScript needs to know:
1. This is a module file (has import/export)
2. The module name you're augmenting exists
3. The augmentation extends existing declarations rather than creating new ones
The declare module syntax is specifically for extending types from existing modules. If you're creating entirely new type definitions, you don't need declare module—just use regular interface or type declarations.
In monorepo setups with multiple tsconfig.json files, ensure your augmentation files are included in the root tsconfig.json or the specific project's tsconfig that references them. Path mapping (compilerOptions.paths) can affect module resolution.
When augmenting third-party libraries, ensure the package is installed and TypeScript can find its type definitions. Libraries without @types/* packages or type definitions in the package might not support module augmentation.
The declaration merging behavior in TypeScript means that multiple declare module blocks for the same module will be merged together. This allows you to split augmentations across multiple files as long as each has proper module context.
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
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript