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.
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
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 [email protected]Common 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"### 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));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