How to fix Module has no exported member 'X' in TypeScript
This TypeScript error (TS2305) occurs when you try to import a named export that doesn't exist in the module. Common causes include typos in import names, incorrect export statements, or version mismatches between packages. The fix involves verifying the correct export names and ensuring proper module structure.
Quick fix
Fixes TS2305
// In the source file (e.g., utils.ts), check exports:
export const formatDate = () => { /* ... */ }; // Named export
export default function helper() { /* ... */ }; // Default export
export { formatDate as format }; // Renamed export
// Common mistakes:
const notExported = () => { /* ... */ }; // NOT exported - can't import this
export { notExported }; // Now it's exported- Verify the exact export name in the source module
- Fix import/export syntax mismatches
- Check for typos and case sensitivity
- Update package versions and check API changes
// In the source file (e.g., utils.ts), check exports:export const formatDate = () => { /* ... */ }; // Named exportexport default function helper() { /* ... */ }; // Default exportexport { formatDate as format }; // Renamed export// Common mistakes:const notExported = () => { /* ... */ }; // NOT exported - can't import thisexport { notExported }; // Now it's exportedModule has no exported member 'X'
What this error means
The "Module has no exported member" error (TS2305) appears when TypeScript cannot find the specific named export you're trying to import from a module. This happens because the export doesn't exist, has a different name, or isn't accessible from your current module context. TypeScript's module system requires explicit exports - you can only import what has been exported. When you write `import { Something } from "./module"`, TypeScript checks if `Something` is in the module's export list. If not, you get TS2305. Common scenarios include: 1. **Typos in import names**: Importing `Component` when the export is `MyComponent` 2. **Missing export statements**: Forgetting to add `export` keyword before a declaration 3. **Default vs named import confusion**: Using `import { Something } from "module"` when it's a default export 4. **Version mismatches**: Importing from an older/newer version of a package with different exports 5. **Module resolution issues**: TypeScript looking at wrong declaration files or incorrect paths
Typical symptoms
- Compilation fails with 'Module has no exported member X' error
- Error code TS2305 appears in compiler output
- IDE shows red underlines on specific import statements
- Auto-complete doesn't suggest the imported name
- Error occurs for some imports but not others from the same module
- Recently updated packages show import errors
Common causes
- Typo in the imported name (case sensitivity or spelling error)
- Missing export statement in the source module
- Using named import syntax for a default export (or vice versa)
- Package version mismatch - importing from wrong API version
- Incorrect module path - importing from wrong file
- Declaration files (.d.ts) out of sync with actual JavaScript exports
- Circular dependencies causing export resolution issues
- Using private/internal APIs not meant for public consumption
How to fix "Module has no exported member 'X'"
First, check what's actually exported from the module you're importing from:
// In the source file (e.g., utils.ts), check exports:
export const formatDate = () => { /* ... */ }; // Named export
export default function helper() { /* ... */ }; // Default export
export { formatDate as format }; // Renamed export
// Common mistakes:
const notExported = () => { /* ... */ }; // NOT exported - can't import this
export { notExported }; // Now it's exportedQuick ways to check exports:
- Open the source file and look for export keywords
- Use VS Code's "Go to Definition" (F12) on the import
- Check package documentation for correct export names
- Use console.log(module) in JavaScript to see available exports
Ensure you're using the correct import syntax for the export type:
// SOURCE MODULE exports:
export const myFunction = () => {}; // Named export
export default class MyComponent {}; // Default export
// CORRECT imports:
import { myFunction } from "./module"; // Named import
import MyComponent from "./module"; // Default import (no braces)
// WRONG imports that cause TS2305:
import { MyComponent } from "./module"; // Trying named import for default export
import myFunction from "./module"; // Trying default import for named export
// Mixed imports (both default and named):
import MyComponent, { myFunction } from "./module";For modules with both default and named exports:
// In module.ts:
export default mainFunction;
export const helper1 = () => {};
export const helper2 = () => {};
// Correct import:
import mainFunction, { helper1, helper2 } from "./module";Module exports are case-sensitive. Verify exact spelling:
// In utils.ts:
export const formatDate = () => {}; // lowercase 'f', uppercase 'D'
// CORRECT:
import { formatDate } from "./utils";
// WRONG - various typos:
import { FormatDate } from "./utils"; // Wrong case
import { formatdate } from "./utils"; // Wrong case
import { formatDate } from "./utils"; // Typo in 'Date'
import { formateDate } from "./utils"; // Missing 't'
// Use IDE autocomplete to avoid typos:
// Type "format" and let VS Code suggest "formatDate"Common patterns to watch for:
- React components: export const Button vs export const button
- Utility functions: formatDate vs format_date vs FormatDate
- Constants: MAX_SIZE vs maxSize vs MaxSize
Package APIs change between versions. Check if you're using the correct version:
# Check installed version
npm list package-name
# Check what version your package.json expects
cat package.json | grep "package-name"
# Compare with documentation
# Visit npmjs.com/package/package-name or GitHub releases
# Update to latest version (if compatible)
npm install package-name@latest
# Or install specific version
npm install package-name@1.2.3Common breaking changes:
- Major version bumps (1.x → 2.x): Often remove or rename exports
- Library migrations: React Router v5 → v6 changed export patterns
- Framework updates: Next.js 12 → 13 changed many exports
Check the package's changelog for export changes:
# Many packages include migration guides
# Check GitHub releases or official docsEnsure you're importing from the correct file path:
// WRONG - importing from wrong file
import { formatDate } from "./utils/index"; // Should be "./utils"
// CORRECT - check actual file structure
// Project structure:
// src/
// utils/
// index.ts // Re-exports everything
// date.ts // Has formatDate export
// string.ts // Has other utilities
// In index.ts (re-export file):
export { formatDate } from "./date";
export { capitalize } from "./string";
// Now you can import from index:
import { formatDate, capitalize } from "./utils";
// Or import directly from date.ts:
import { formatDate } from "./utils/date";Check for barrel files (index.ts) that re-export:
// If ./components/index.ts doesn't export Button,
// but ./components/Button.ts does, you need:
import { Button } from "./components/Button";
// NOT:
import { Button } from "./components"; // Unless index.ts re-exports itTypeScript declaration files (.d.ts) must match actual exports:
// If using third-party packages without types:
// Create a declaration file (e.g., types/custom.d.ts)
declare module "untyped-package" {
export const someFunction: () => void;
export interface Config { /* ... */ }
}
// Ensure tsconfig.json includes your declaration files:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
},
"include": ["src/**/*", "types/**/*"]
}Common declaration issues:
- Outdated @types packages: Run npm update @types/package-name
- Missing types: Check if package has index.d.ts in its distribution
- Incorrect module augmentation: When extending existing types
Check what TypeScript sees:
# Generate declaration files to see exports
npx tsc --declaration --emitDeclarationOnly
# Or check node_modules for .d.ts files
find node_modules/package-name -name "*.d.ts"Advanced notes
### Understanding Module Systems
TypeScript supports different module systems that affect exports:
CommonJS (Node.js style):
// Exporting
module.exports = { myFunction, myConstant };
// or
exports.myFunction = myFunction;
// Importing in TypeScript (with esModuleInterop: true)
import * as utils from "./utils"; // utils = { myFunction, myConstant }
import { myFunction } from "./utils"; // Only works if .d.ts has named exportsES Modules (Modern JavaScript):
// Exporting
export const myFunction = () => {};
export default mainFunction;
// Importing
import { myFunction } from "./module";
import mainFunction from "./module";### Barrel Files and Re-exports
Barrel files (index.ts) simplify imports but can cause issues:
// src/components/index.ts
export { Button } from "./Button";
export { Input } from "./Input";
// Missing: export { Card } from "./Card";
// User tries to import Card (TS2305):
import { Card } from "./components"; // Error!
import { Card } from "./components/Card"; // Works### Dynamic Imports and Type-Only Imports
For dynamic imports or type-only usage:
// Type-only import (doesn't exist at runtime)
import type { User } from "./types";
// Dynamic import (runtime)
const module = await import("./utils");
const result = module.someFunction(); // No type checking here
// With dynamic import types:
import("./utils").then((module) => {
// module is typed if .d.ts exists
});### Module Augmentation
When extending third-party module types:
// types/express.d.ts
declare module "express" {
interface Request {
user?: User; // Adding custom property
}
}
// Now TypeScript knows about req.user### Checking Export Maps
Modern packages use exports field in package.json:
{
"exports": {
".": {
"import": "./dist/esm/index.js",
"require": "./dist/cjs/index.js",
"types": "./dist/types/index.d.ts"
},
"./utils": {
"import": "./dist/esm/utils.js",
"require": "./dist/cjs/utils.js",
"types": "./dist/types/utils.d.ts"
}
}
}This controls which subpaths are exposed. If ./utils isn't in exports map, you can't import from it.
### Debugging Tools
1. TypeScript trace resolution:
npx tsc --traceResolution | grep "module-name"2. Check compiled JavaScript:
npx tsc --outDir ./temp && cat ./temp/module.js3. VS Code TypeScript server:
- Restart with: Cmd/Ctrl + Shift + P → "TypeScript: Restart TS Server"
- Check output with: View → Output → TypeScript
4. Module introspection:
// In JavaScript (temporary)
const module = require("./module");
console.log(Object.keys(module));Frequently asked questions
- What does "TS2305" mean?
- The "Module has no exported member" error (TS2305) appears when TypeScript cannot find the specific named export you're trying to import from a module. This happens because the export doesn't exist, has a different name, or isn't accessible from your current module context. TypeScript's module system requires explicit exports - you can only import what has been exported.
- How do I fix "TS2305"?
- This TypeScript error (TS2305) occurs when you try to import a named export that doesn't exist in the module. Common causes include typos in import names, incorrect export statements, or version mismatches between packages. The fix involves verifying the correct export names and ensuring proper module structure.
- What causes "TS2305"?
- Typo in the imported name (case sensitivity or spelling error) Missing export statement in the source module Using named import syntax for a default export (or vice versa)
- Is the "TS2305" 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 - Modules(Official Docs)
- 📖TypeScript Handbook - Module Resolution(Official Docs)
- 📖TypeScript TSConfig - Module(Official Docs)
- 🐙