Fix: TypeScript Could Not Find Declaration File — Module Has No Type Information
Quick Answer
How to fix TypeScript 'could not find a declaration file for module' errors — installing @types packages, writing custom .d.ts files, module augmentation, and tsconfig paths.
The Error
TypeScript can’t find type information for a module:
Could not find a declaration file for module 'some-library'.
'/path/to/node_modules/some-library/index.js' implicitly has an 'any' type.
Try `npm i --save-dev @types/some-library` if it exists
or add a new declaration (.d.ts) file containing `declare module 'some-library';`Or an error after installing the types package:
TS2305: Module '@types/some-library' has no exported member 'SomeType'.Or when importing from a subpath:
TS2307: Cannot find module 'some-library/utils' or its corresponding type declarations.Or for a local file:
TS2307: Cannot find module './config' or its corresponding type declarations.Why This Happens
TypeScript requires type information for every module. It looks for types in this order:
- Bundled types —
typesortypingsfield in the module’spackage.json(included by the package itself) - DefinitelyTyped —
@types/<package-name>innode_modules/@types/ - Type roots in
tsconfig.jsontypeRootsfield - Declaration files —
.d.tsfiles matching the import path
When none of these exist, TypeScript can’t type-check usage of the module and reports the error.
Common specific causes:
- No
@typespackage exists — many smaller or newer packages don’t have community-maintained types - Types package not installed — the
@typespackage exists but wasn’t installed - Package has
exportsmap withouttypescondition — modern packages usingexportsinpackage.jsonneed atypescondition for each export path; without it, TypeScript can’t find subpath types moduleResolutionsetting mismatch — packages usingexportsfields require"moduleResolution": "bundler"or"node16", not the older"node"mode- Local file has wrong extension — importing
./configexpectsconfig.tsorconfig.d.tsto exist
Fix 1: Install the @types Package
Most popular JavaScript packages have community-maintained types on DefinitelyTyped:
npm install --save-dev @types/package-name
# Common examples
npm install --save-dev @types/node
npm install --save-dev @types/express
npm install --save-dev @types/lodash
npm install --save-dev @types/jest
npm install --save-dev @types/react @types/react-dom
npm install --save-dev @types/uuid
npm install --save-dev @types/multerFind if an @types package exists:
npm search @types/package-name
# Or check the TypeScript registry
# https://www.typescriptlang.org/dt/searchAfter installing, verify TypeScript finds the types:
npx tsc --noEmit # Should compile without the error nowFix 2: Add a Module Declaration for Untyped Packages
If no @types package exists, declare the module’s type as any to silence the error:
// src/types/untyped-modules.d.ts
// Quick fix — module is typed as 'any'
declare module 'some-untyped-library';
declare module 'another-untyped-library';Better approach — write minimal type declarations:
// src/types/some-library.d.ts
declare module 'some-library' {
export interface Config {
apiKey: string;
timeout?: number;
}
export function initialize(config: Config): void;
export function request(url: string): Promise<Response>;
export default {
initialize,
request,
};
}Declare subpath modules:
// src/types/some-library.d.ts
declare module 'some-library' {
export function mainFunction(): void;
}
declare module 'some-library/utils' {
export function helperFunction(input: string): string;
}
declare module 'some-library/*' {
// Wildcard — matches any subpath
const value: unknown;
export default value;
}Pro Tip: Writing stub type declarations (with
anytypes) is a faster path to progress than waiting for full type coverage. Once you have the stubs, you can refine individual types as you use them. Open a PR to DefinitelyTyped with your types to contribute back to the community.
Fix 3: Fix tsconfig.json to Include Declaration Files
TypeScript must be configured to find your custom .d.ts files:
// tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"moduleResolution": "bundler", // or "node16" for ESM
"strict": true,
"outDir": "./dist",
"rootDir": "./src",
// Where TypeScript looks for global type declarations
"typeRoots": [
"./node_modules/@types",
"./src/types" // Your custom .d.ts files directory
],
// Explicit list of type packages to include (optional)
// "types": ["node", "jest"]
},
"include": [
"src/**/*",
"src/types/**/*.d.ts" // Ensure .d.ts files are included
]
}Check that your types directory structure is correct:
src/
├── types/
│ ├── global.d.ts # Global augmentations
│ ├── untyped-modules.d.ts # Declarations for untyped npm packages
│ └── env.d.ts # Environment variable types
├── components/
└── index.tsFix 4: Fix moduleResolution for Modern Package Exports
Many modern packages use the exports field in package.json for subpath exports. The older "moduleResolution": "node" doesn’t support this:
// The library's package.json (you can't change this)
{
"exports": {
".": { "types": "./dist/index.d.ts", "default": "./dist/index.js" },
"./utils": { "types": "./dist/utils.d.ts", "default": "./dist/utils.js" }
}
}// Your tsconfig.json — update moduleResolution
{
"compilerOptions": {
// OLD (Node 10 resolution — doesn't understand 'exports' field)
// "moduleResolution": "node",
// CORRECT — supports package exports
"moduleResolution": "bundler", // For Vite, esbuild, webpack bundlers
// or:
"moduleResolution": "node16", // For Node.js 16+ native ESM
// or:
"moduleResolution": "nodenext" // For latest Node.js ESM support
}
}Verify the package includes type declarations for its exports:
cat node_modules/some-package/package.json | grep -A 20 '"exports"'
# Look for "types" entries in each export pathFix 5: Module Augmentation for Third-Party Types
When a package’s types are missing specific members that exist at runtime (version mismatch, missing types), extend them:
// src/types/express.d.ts — add properties to Express's Request type
import { User } from '../models/User';
declare global {
namespace Express {
interface Request {
user?: User; // Added by passport.js or custom middleware
sessionId?: string;
startTime?: number;
}
}
}
// Must export something (even empty) to make this a module
export {};Augment a specific package’s module:
// src/types/vue.d.ts — add global properties to Vue component instances
import { ComponentCustomProperties } from 'vue';
import { Store } from 'vuex';
import { Router } from 'vue-router';
declare module '@vue/runtime-core' {
interface ComponentCustomProperties {
$store: Store<State>;
$router: Router;
$filters: {
formatDate: (date: Date) => string;
formatCurrency: (amount: number) => string;
};
}
}
export {};Augment an npm package’s exported types:
// src/types/axios.d.ts — extend Axios request config
declare module 'axios' {
interface AxiosRequestConfig {
_retry?: boolean; // Custom flag for retry logic
_skipAuth?: boolean; // Skip auth header on this request
}
}
export {};Fix 6: Handle JSON and Asset Imports
TypeScript doesn’t know the types of JSON files or asset imports without configuration:
// Import JSON files
// tsconfig.json — enable resolveJsonModule
{
"compilerOptions": {
"resolveJsonModule": true
}
}
// Now TypeScript infers the type from the JSON structure
import config from './config.json';
console.log(config.apiUrl); // Typed correctlyCSS Modules:
// src/types/css-modules.d.ts
declare module '*.module.css' {
const styles: Record<string, string>;
export default styles;
}
declare module '*.module.scss' {
const styles: Record<string, string>;
export default styles;
}Image and file imports:
// src/types/assets.d.ts
declare module '*.png' {
const url: string;
export default url;
}
declare module '*.svg' {
import React from 'react';
const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
export { ReactComponent };
const url: string;
export default url;
}
declare module '*.jpg' {
const url: string;
export default url;
}
declare module '*.webp' {
const url: string;
export default url;
}Environment variables in Vite:
// src/vite-env.d.ts (Vite creates this automatically — add your env vars)
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_API_URL: string;
readonly VITE_APP_TITLE: string;
readonly VITE_SENTRY_DSN?: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}Fix 7: Path Aliases in tsconfig
If you use path aliases (@/components/Button) and TypeScript can’t find the module, configure paths:
// tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@/*": ["src/*"],
"@components/*": ["src/components/*"],
"@hooks/*": ["src/hooks/*"],
"@utils/*": ["src/utils/*"],
"@types/*": ["src/types/*"]
}
}
}For bundlers, also configure the alias there (TypeScript paths only affect type-checking, not bundling):
// vite.config.ts
import { defineConfig } from 'vite';
import path from 'path';
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
});// webpack.config.js
module.exports = {
resolve: {
alias: {
'@': path.resolve(__dirname, 'src'),
},
},
};Still Not Working?
Restart the TypeScript language server after any changes to .d.ts files or tsconfig.json. In VS Code: Ctrl+Shift+P → “TypeScript: Restart TS Server”.
Check if the .d.ts file is actually being picked up:
npx tsc --traceResolution 2>&1 | grep "some-library"
# Shows every file TypeScript checks when resolving the moduleTriple-slash references — if a .d.ts file depends on other types, add a reference directive:
/// <reference types="node" />
/// <reference path="../other-types.d.ts" />
declare module 'my-module' {
import { EventEmitter } from 'events'; // Uses Node.js types via reference
export class MyEmitter extends EventEmitter {}
}Version mismatch between @types and the library — if @types/foo is version 2.x but foo is version 3.x, there may be missing or incorrect types. Install the matching version:
npm install --save-dev @types/foo@3For related TypeScript errors, see Fix: TypeScript Type Not Assignable and Fix: TypeScript Enum Not Working.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: pdf-lib Not Working — PDF Not Generating, Fonts Not Embedding, or Pages Blank
How to fix pdf-lib issues — creating PDFs from scratch, modifying existing PDFs, embedding fonts and images, form filling, merging documents, and browser and Node.js usage.
Fix: Pusher Not Working — Events Not Received, Channel Auth Failing, or Connection Dropping
How to fix Pusher real-time issues — client and server setup, channel types, presence channels, authentication endpoints, event binding, connection management, and React integration.
Fix: date-fns Not Working — Wrong Timezone Output, Invalid Date, or Locale Not Applied
How to fix date-fns issues — timezone handling with date-fns-tz, parseISO vs new Date, locale import and configuration, DST edge cases, v3 ESM migration, and common format pattern mistakes.
Fix: Zod Validation Not Working — safeParse Returns Wrong Error, transform Breaks Type, or discriminatedUnion Fails
How to fix Zod schema validation issues — parse vs safeParse, transform and preprocess, refine for cross-field validation, discriminatedUnion, error formatting, and common schema mistakes.