TypeScript error

TS7016: A package without type declarations

  • Error TS7016
  • Reported with noImplicitAny
  • Reported with strict
  • Tested with TypeScript 5.9

error TS7016: Could not find a declaration file for module 'legacy-slugify'. '/project/node_modules/legacy-slugify/index.js' implicitly has an 'any' type. is reported when an import resolves to a package's JavaScript but no type declarations: no types in its package.json, no .d.ts next to it, no @types package. Under noImplicitAny the resulting any is an error.

A jsconfig.json makes this rarer than in TypeScript projects: it sets maxNodeModuleJsDepth to 2, so the checker reads the package's own JavaScript (and its JSDoc) for types. You meet TS7016 in a tsconfig.json with allowJs, with maxNodeModuleJsDepth: 0 as in the example, or for packages deeper than the limit.

At a glance

CodeTS7016
MessageCould not find a declaration file for module '{0}'. '{1}' implicitly has an 'any' type.
TypeScript's categoryerror
Listed underModules and imports
Turned on by noImplicitAny, strict
Turned off by maxNodeModuleJsDepth
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The message is TypeScript's own text from its diagnostic messages file (Apache-2.0); {0} and {1} are filled in by tsc for each error.

What it looks like

app.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: app.js(2,25): error TS7016: Could not find a declaration file for module 'legacy-slugify'. '/project/node_modules/legacy-slugify/index.js' implicitly has an 'any' type. Try `npm i --save-dev @types/legacy-slugify` if it exists or add a new declaration (.d.ts) file containing `declare module 'legacy-slugify';` 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. app.js(2,25): error TS7016: Could not find a declaration file for module 'legacy-slugify'. '/project/node_modules/legacy-slugify/index.js' implicitly has an 'any' type. Try `npm i --save-dev @types/legacy-slugify` if it exists or add a new declaration (.d.ts) file containing `declare module 'legacy-slugify';` 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. app.js(2,25): error TS7016: Could not find a declaration file for module 'legacy-slugify'. '/project/node_modules/legacy-slugify/index.js' implicitly has an 'any' type. Try `npm i --save-dev @types/legacy-slugify` if it exists or add a new declaration (.d.ts) file containing `declare module 'legacy-slugify';` checked 21 October 2026
import { slugify } from "legacy-slugify";error TS7016: Could not find a declaration file for module 'legacy-slugify'. '/project/node_modules/legacy-slugify/index.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/legacy-slugify` if it exists or add a new declaration (.d.ts) file containing `declare module 'legacy-slugify';`

export const slug = slugify("Cotton tee");
A JavaScript-only package the checker does not read.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "maxNodeModuleJsDepth": 0
  },
  "include": ["*.js"]
}

What causes it

  • The package publishes JavaScript only, and no @types/<name> package is installed.
  • The checker is not reading packages' JavaScript: maxNodeModuleJsDepth is 0 (the tsconfig.json default) or the package is beyond the depth.
  • noImplicitAny is on (part of strict).

How to fix it

Install the @types package, if there is one

The message suggests npm i --save-dev @types/<name>. DefinitelyTyped publishes types for many JavaScript-only packages; a types: [] list in your config does not stop the import from finding it.

app.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
import { slugify } from "legacy-slugify";

export const slug = slugify("Cotton tee");
The package's types from an @types package.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "maxNodeModuleJsDepth": 0
  },
  "include": ["*.js"]
}

Or write a small declaration file

Write a .d.ts file with declare module "legacy-slugify" { ... } describing just the functions you use, matched by include. declare module "legacy-slugify"; with no body also silences the error, but makes every import any.

app.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
import { slugify } from "legacy-slugify";

export const slug = slugify("Cotton tee");
A local declaration file for the package.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": [],
    "maxNodeModuleJsDepth": 0
  },
  "include": ["*.js", "types/*.d.ts"]
}

Or let the checker read the package's JavaScript

With the jsconfig.json default (maxNodeModuleJsDepth 2), the checker reads the package's files and takes types from their code and JSDoc. That works best for packages that are documented with JSDoc, like the one in this example.

app.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
import { slugify } from "legacy-slugify";

export const slug = slugify("Cotton tee");
A package with JSDoc in its JavaScript, read at the jsconfig.json default depth.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Gotchas

  • When the checker reads a package's JavaScript, an untyped parameter inside the package is reported as TS7006 against the package's own file under noImplicitAny, whether or not your code calls that function. A .d.ts or an @types package avoids that.
  • The path in the message is the file the import resolved to (tsc prints the full path; on this site examples live at /project).

Sources

Last reviewed 20 October 2026.