Fix TS7016: Could Not Find Declaration File for Module
Technology

Fix TS7016: Could Not Find Declaration File for Module

TS7016 fires when you import an untyped JavaScript module under noImplicitAny. The right fix is usually `npm i -D @types/X` — but sometimes the package already ships types, and sometimes you need to write a one-line declaration.

2026-06-18
8 min read
Fix TS7016: Could Not Find Declaration File for Module

You import a perfectly normal npm package and TypeScript stops you:

text
Could not find a declaration file for module 'some-lib'.
'.../node_modules/some-lib/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/some-lib` if it exists or add a new
  declaration (.d.ts) file containing `declare module 'some-lib';`

This is TS7016. TypeScript even prints its own two suggested fixes. This guide explains when each is right, plus the case the message doesn't mention: the package may already ship types.

Why it happens#

TS7016 fires when all three are true:

  1. You import a module that resolves to a plain JavaScript file with no bundled .d.ts, and
  2. there is no @types/X package installed, and
  3. noImplicitAny is on (it is, under strict).

Without type information the module would silently become any. The noImplicitAny docs put it plainly: with the flag on, "TypeScript will issue an error whenever it would have inferred any." So TS7016 is the protection working — not a broken install.

Fix 1 (preferred) — Install the DefinitelyTyped types#

bash
npm install --save-dev @types/some-lib

How to know it exists: DefinitelyTyped publishes type packages to npm under the @types scope with the same name as the underlying package (react@types/react). Per the handbook, "TypeScript automatically finds type definitions under node_modules/@types, so there's no other step needed." If the install errors with 404, no community types exist — go to Fix 3.

Fix 2 — Check if the package already ships types#

Sometimes TS7016 is misdiagnosed: the package does bundle types and you're chasing a phantom. Look in the dependency's package.json for a types (or its synonym typings) field:

json
{
  "main": "./lib/main.js",
  "types": "./lib/main.d.ts"
}

If a package bundles types but you still see TS7016, suspect a stale install, a typesVersions mismatch for your TS version, or an exports map that doesn't expose the .d.ts under your moduleResolution. The fix there is reinstalling or adjusting module resolution — not adding @types.

Fix 3 — Write a local declaration#

When neither @types/X nor bundled types exist, declare the module yourself. Create a file like src/types/some-lib.d.ts. The minimal "make it any" form (TypeScript's own second suggestion):

typescript
// src/types/some-lib.d.ts
declare module 'some-lib';

Better — a typed stub keeps real safety instead of opting the whole module into any:

typescript
declare module 'some-lib' {
  export function doThing(input: string): string;
  export interface Options {
    retries?: number;
    timeout?: number;
  }
  export const version: string;
}
Make sure the compiler sees it

The .d.ts must be inside your tsconfig include scope, or TypeScript won't pick it up. If it's ignored, check include/files in tsconfig.

Last resort — turn off the check#

jsonc
// silences ALL of these, project-wide
{ "compilerOptions": { "noImplicitAny": false } }

Or // @ts-ignore on the import line. Both work and both are bad:

Don't
// @ts-ignore — kills checking for this import and breaks silently when the lib changes
Do
npm i -D @types/some-lib — or a typed declare module stub: error gone, safety kept
When this won't work
  • The package ships ESM-only types but your moduleResolution is node16/nodenext/bundler and its exports map hides the .d.ts — that's a resolution problem, not a missing-types one.
  • Your @types/X version drifted from the runtime package version — reinstall to match, or you'll get wrong types rather than missing ones.

Decision guide#

| Check | Result | Do this | |---|---|---| | npm i -D @types/X succeeds | Community types exist | Done | | Package's package.json has types/typings | It ships its own | Reinstall / fix resolution | | Neither exists | Truly untyped | declare module 'X'; (+ a typed stub) | | Nothing else and you're in a hurry | — | @ts-ignore (last resort) |

Official references: Consuming declaration files, Type declarations, module .d.ts template, noImplicitAny.

Frequently Asked Questions#

How do I fix "Could not find a declaration file for module"?#

Run npm install --save-dev @types/X first — most popular packages have community types on DefinitelyTyped, auto-discovered in node_modules/@types. If none exist, write a local declare module 'X'; inside your tsconfig include scope.

Why does this error only appear with strict mode?#

It's gated by noImplicitAny, which strict enables. Without it an untyped module silently becomes any; with it, TypeScript surfaces TS7016 instead. That's the protection working.

Should I just use @ts-ignore to silence it?#

Prefer @types or a declaration. @ts-ignore suppresses the one error but discards type checking for that import and breaks across refactors. Disabling noImplicitAny removes the protection project-wide. Both are last resorts.

Frequently Asked Questions

|

Have more questions? Contact us

Written by

Mahdi Br
Mahdi Br

Full-Stack Dev — Next.js & Supabase

Solo developer building SaaS products with Next.js and Supabase. Writing about production patterns the official docs skip.

Remote

One email a month — no fluff

RLS gotchas, Next.js cache debugging, and the one Supabase setting that bit me last month.