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.
You import a perfectly normal npm package and TypeScript stops you:
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:
- You import a module that resolves to a plain JavaScript file with no bundled
.d.ts, and - there is no
@types/Xpackage installed, and noImplicitAnyis on (it is, understrict).
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#
npm install --save-dev @types/some-libHow 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:
{
"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):
// 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:
declare module 'some-lib' {
export function doThing(input: string): string;
export interface Options {
retries?: number;
timeout?: number;
}
export const version: string;
}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#
// silences ALL of these, project-wide
{ "compilerOptions": { "noImplicitAny": false } }Or // @ts-ignore on the import line. Both work and both are bad:
- The package ships ESM-only types but your
moduleResolutionisnode16/nodenext/bundlerand itsexportsmap hides the.d.ts— that's a resolution problem, not a missing-types one. - Your
@types/Xversion 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.
Related Articles#
- TypeScript Migration Guide: Moving a JS Codebase in 2026
- Set a New Property on
windowin TypeScript - Fix Next.js Build Error Module Not Found After Deploy
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
One email a month — no fluff
RLS gotchas, Next.js cache debugging, and the one Supabase setting that bit me last month.
Continue Reading
Fix TS2305: Module Has No Exported Member in TypeScript
TS2305 says the export you're importing doesn't exist under that name. The cause is almost always one of: a typo, default-vs-named confusion, a CJS/ESM interop mismatch, or @types drifting from the runtime package. Each has a precise fix.
Fix TS2564: Property Has No Initializer in TypeScript
TS2564 fires when a class field is typed but never guaranteed to be set. The fix depends on WHY it's unset: a default value, constructor assignment, the definite-assignment `!`, or an optional `?`. Picking the wrong one hides real bugs.
Fix Postgres 'Could Not Serialize Access' (40001)
Postgres aborts one transaction with 40001 to prevent a serialization anomaly. The docs are explicit: apps using REPEATABLE READ or SERIALIZABLE must be prepared to retry. Here's the correct retry loop and how to reduce conflicts.
Browse by Topic
Find stories that matter to you.
