Skip to content

Fix: TypeScript Could Not Find Declaration File — Module Has No Type Information

FixDevs ·

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:

  1. Bundled typestypes or typings field in the module’s package.json (included by the package itself)
  2. DefinitelyTyped@types/<package-name> in node_modules/@types/
  3. Type roots in tsconfig.json typeRoots field
  4. Declaration files.d.ts files 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 @types package exists — many smaller or newer packages don’t have community-maintained types
  • Types package not installed — the @types package exists but wasn’t installed
  • Package has exports map without types condition — modern packages using exports in package.json need a types condition for each export path; without it, TypeScript can’t find subpath types
  • moduleResolution setting mismatch — packages using exports fields require "moduleResolution": "bundler" or "node16", not the older "node" mode
  • Local file has wrong extension — importing ./config expects config.ts or config.d.ts to 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/multer

Find if an @types package exists:

npm search @types/package-name

# Or check the TypeScript registry
# https://www.typescriptlang.org/dt/search

After installing, verify TypeScript finds the types:

npx tsc --noEmit  # Should compile without the error now

Fix 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 any types) 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.ts

Fix 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 path

Fix 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 correctly

CSS 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 module

Triple-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@3

For related TypeScript errors, see Fix: TypeScript Type Not Assignable and Fix: TypeScript Enum Not Working.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles