How to fix Augmenting module 'X' but no export found in original in TypeScript
This error occurs when you try to augment (extend) a module using TypeScript's declaration merging, but the original module doesn't export the type or interface you're trying to augment. The fix involves ensuring the module exports the expected types or correcting your augmentation syntax.
Quick fix
Fixes TS2388
// WRONG - if Response is not exported
declare module 'my-lib' {
interface Response {
customField: string;
}
}- Verify the module exports what you're trying to augment
- Check if the export uses a different name
- Verify you're augmenting the correct module path
- Check for re-export issues
// WRONG - if Response is not exporteddeclare module 'my-lib' {interface Response {customField: string;}}Augmenting module 'X' but no export found in original
What this error means
TypeScript's module augmentation feature allows you to extend existing module declarations without modifying the original files. When you use `declare module 'module-name'`, you're telling TypeScript to merge your new declarations with the original module's exports. This error appears when: 1. The original module doesn't actually export what you're trying to augment 2. You're augmenting a module that doesn't exist or isn't installed 3. There's a mismatch between how you declared the export and how the original module exports it 4. You're using re-exported modules (indirect exports from index files) Module augmentation is particularly useful for adding types to third-party libraries, extending global objects, or merging namespaces. However, TypeScript strictly enforces that you can only augment exports that actually exist in the original module.
Typical symptoms
- TypeScript error: 'Augmenting module X but no export found in original'
- Error appears in .d.ts declaration files or declaration merge statements
- IntelliSense shows the augmented type but compiler rejects the code
- Build fails with 'TS2388' error code
- Works in one environment but fails in another (different TypeScript versions)
- Error occurs when trying to extend interfaces from a third-party library
Common causes
- The module you're augmenting doesn't export the interface/type you're trying to extend (most common)
- The export exists but uses a different name than what you're augmenting
- You're augmenting a re-exported module and the original export path is different
- Module uses named exports via 'export { Something }' but you're treating it as a default export
- TypeScript version mismatch—older versions have different module augmentation rules
- The module is not properly typed (no .d.ts files or type definitions)
- You're augmenting an ambient module that doesn't exist in the resolved modules
How to fix "Augmenting module 'X' but no export found in original"
First, confirm that the original module actually exports the type or interface you want to augment. Check the library's type definition file or source code.
For example, if you're trying to augment a type called Response:
// WRONG - if Response is not exported
declare module 'my-lib' {
interface Response {
customField: string;
}
}Check the library's index.d.ts or package.json types field to see what's actually exported:
cat node_modules/my-lib/index.d.ts | grep -i "export.*Response"Or look in the actual source:
cat node_modules/my-lib/package.json | grep -E '"types"|"typings"'Sometimes the export is named differently than expected. For example, the library might export HttpResponse but you're trying to augment Response.
// WRONG - augmenting the wrong name
declare module 'http-lib' {
interface Response {
custom: string;
}
}
// CORRECT - use the actual export name
declare module 'http-lib' {
interface HttpResponse {
custom: string;
}
}Check what names are actually exported:
grep "^export" node_modules/your-lib/index.d.tsModule augmentation requires the exact module path. For scoped packages or submodules, use the full path:
// For @scope/package
declare module '@scope/package' {
interface Response {
custom: string;
}
}
// For submodules
declare module '@scope/package/utils' {
interface Response {
custom: string;
}
}
// NOT just 'package' - that won't find the module
declare module 'package' {
interface Response {
custom: string;
}
}To find the exact path, check how the module is imported in your code:
import { Response } from '@scope/package/api'; // Use '@scope/package/api' for augmentation
import { Response } from 'my-lib'; // Use 'my-lib' for augmentationIf a module re-exports types using export * from, TypeScript may not allow augmentation on the re-exporting module. You need to augment the original source module instead.
For example, if node_modules/my-lib/index.ts contains:
export * from './types/response';Then augment the original source path:
// WRONG - augmenting the re-export
declare module 'my-lib' {
interface Response {
custom: string;
}
}
// CORRECT - augment the original source
declare module 'my-lib/types/response' {
interface Response {
custom: string;
}
}Check the module structure:
cat node_modules/my-lib/index.d.tsIf you're defining your own types to augment, use inline export keywords instead of separate export statements:
// WRONG - export clause can cause issues
interface MyType {
value: string;
}
export { MyType };
// CORRECT - inline export
export interface MyType {
value: string;
}This prevents duplicate identifier conflicts during module augmentation.
Module augmentation only works with direct exports, not re-exports. If the original module only re-exports from another package:
// In original-lib/index.ts
export type Response = require('other-lib').Response; // This is a re-export
// TypeScript may reject augmentation because Response is not directly exported
declare module 'original-lib' {
interface Response {
custom: string;
}
}In this case, you may need to augment the source library instead or use a different approach.
Advanced notes
### Module Augmentation Best Practices
Use separate .d.ts files for augmentations: Keep augmentations in their own declaration files for clarity:
// types/augmentations.d.ts
declare module 'express' {
interface Request {
userId?: string;
}
}Import the augmented module first: Always import the original module before declaring augmentations, or the augmentation won't work:
import 'my-lib'; // Import first
declare module 'my-lib' {
interface Config {
custom: string;
}
}Troubleshooting with TypeScript Compiler:
If you're still unsure what's exported, use the TypeScript compiler in declaration mode:
npx tsc --declaration --emitDeclarationOnly --noEmitTypeScript Version Compatibility: Module augmentation behavior varies slightly between TypeScript versions. If updating TypeScript fixes the issue, that's a clue that your augmentation syntax relies on newer features.
Alternative: Use Namespaces: For some use cases, extending a namespace is safer than module augmentation:
// If the module exports a namespace
declare namespace MyLib {
interface Config {
custom: string;
}
}Check tsconfig.json: Ensure your tsconfig includes the types directory and has the right module resolution:
{
"compilerOptions": {
"moduleResolution": "node",
"typeRoots": ["./node_modules/@types", "./types"],
"skipLibCheck": false
}
}Frequently asked questions
- What does "TS2388" mean?
- TypeScript's module augmentation feature allows you to extend existing module declarations without modifying the original files. When you use declare module 'module-name', you're telling TypeScript to merge your new declarations with the original module's exports. This error appears when: 1.
- How do I fix "TS2388"?
- This error occurs when you try to augment (extend) a module using TypeScript's declaration merging, but the original module doesn't export the type or interface you're trying to augment. The fix involves ensuring the module exports the expected types or correcting your augmentation syntax.
- What causes "TS2388"?
- The module you're augmenting doesn't export the interface/type you're trying to extend (most common) The export exists but uses a different name than what you're augmenting You're augmenting a re-exported module and the original export path is different
- Is the "TS2388" error serious?
- It is a medium-severity error — more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- 📚TypeScript Official Documentation
- 📖TypeScript Handbook - Declaration Merging(Official Docs)
- 📖TypeScript Handbook - Declaration Files(Official Docs)
- 🐙
- 🐙
- 🐙
- 🐙