This TypeScript error appears when importing a JavaScript library that lacks type definitions. TypeScript needs declaration files (.d.ts) to understand the types a module exports. The fix typically involves installing the corresponding @types package or creating custom type declarations.
The "Could not find a declaration file for module" error (TS7016) occurs when TypeScript cannot find type definitions for a module you're importing. This is common when using JavaScript libraries that don't include built-in TypeScript support. TypeScript requires declaration files (.d.ts files) to provide type information about JavaScript modules. These files describe the shape of the module's exports without containing actual implementation code. When TypeScript can't find these declarations, it cannot provide type checking or IntelliSense support. The error message typically includes a suggestion like "Try `npm i --save-dev @types/module-name`" which points to the most common solution. Common scenarios include: 1. **Pure JavaScript packages**: Libraries written in JavaScript without TypeScript types 2. **Missing @types packages**: The library has community-maintained types on DefinitelyTyped but they're not installed 3. **Private/internal packages**: Custom modules that need manual type declarations 4. **Legacy packages**: Older libraries that predate TypeScript's popularity
Most popular JavaScript libraries have community-maintained type definitions on DefinitelyTyped. Install them as dev dependencies:
# General pattern
npm install --save-dev @types/package-name
# Common examples:
npm install --save-dev @types/lodash
npm install --save-dev @types/express
npm install --save-dev @types/node
npm install --save-dev @types/react
npm install --save-dev @types/jqueryThe package name follows the convention @types/original-package-name. After installation, TypeScript should recognize the types:
// This will now have full type support
import _ from "lodash";
import express from "express";Search for available type packages at:
- [TypeScript Type Search](https://www.typescriptlang.org/dt/search)
- [DefinitelyTyped GitHub](https://github.com/DefinitelyTyped/DefinitelyTyped)
If no @types package exists, create your own declaration file. Create a .d.ts file in your project:
// types/my-library.d.ts
declare module "my-library" {
// Export the functions/values you're using
export function someFunction(arg: string): number;
export const someValue: string;
// For default exports
export default function myLibrary(): void;
}For libraries you're not actively using but just need to compile:
// types/my-library.d.ts
// Quick workaround - types everything as 'any'
declare module "my-library";Ensure the declaration file is included in your tsconfig.json:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./types"]
},
"include": ["src/**/*", "types/**/*"]
}Create specific type declarations as you use the library:
// types/my-library.d.ts
declare module "my-library" {
export interface Config {
timeout: number;
retries: number;
}
export class Client {
constructor(config: Config);
connect(): Promise<void>;
disconnect(): void;
}
}Verify TypeScript is looking in the correct directories for type definitions:
{
"compilerOptions": {
// Explicitly specify where to find type definitions
"typeRoots": [
"./node_modules/@types",
"./types"
],
// Alternative: specify exact packages to include
"types": ["node", "react", "lodash"],
// Ensure proper module resolution
"moduleResolution": "node",
"esModuleInterop": true
},
"include": [
"src/**/*",
"types/**/*"
]
}Important notes:
- If you specify types, ONLY those packages will be included (whitelist)
- If types is not specified, ALL packages in typeRoots are included
- If typeRoots is not specified, defaults to ./node_modules/@types
For most projects, you can omit both and let TypeScript use defaults:
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true
}
}If you need to compile quickly and don't need strict type checking for third-party libraries, enable skipLibCheck:
{
"compilerOptions": {
"skipLibCheck": true
}
}What this does:
- Skips type checking of all declaration files (*.d.ts)
- Speeds up compilation significantly
- Still type-checks your own code
- Ignores type errors in node_modules
When to use:
- Temporary fix to unblock development
- Working with libraries that have incomplete types
- Large projects where compilation speed is critical
Trade-offs:
- You lose type safety for third-party libraries
- May miss real type errors in dependencies
- Not a long-term solution for production code
Better long-term approach:
1. Create proper declaration files (see Step 2)
2. Contribute types to DefinitelyTyped
3. Request types from library maintainers
Sometimes @types packages exist but don't match your library version:
# Check installed versions
npm list lodash
npm list @types/lodash
# If versions don't match, install compatible @types
npm install --save-dev @types/[email protected]
# Check package info before installing
npm info @types/package-name versionsCommon version mismatches:
// package.json
{
"dependencies": {
"express": "^5.0.0"
},
"devDependencies": {
// WRONG - types for Express 4
"@types/express": "^4.17.0"
// CORRECT - match major version
"@types/express": "^5.0.0"
}
}If exact version match doesn't exist:
// types/package-name.d.ts
// Import from closest version and extend
import type { SomeType } from "@types/package-name-v4";
declare module "package-name" {
export * from "@types/package-name-v4";
// Add missing types for v5 features
export function newV5Feature(): void;
}TypeScript caches type information. Clear it after installing new @types packages:
# Delete TypeScript build cache
rm -rf node_modules/.cache
rm -rf .tsbuildinfo
# Delete all build output
rm -rf dist build
# Reinstall dependencies
rm -rf node_modules
npm install
# Restart TypeScript server in VS Code
# Cmd/Ctrl + Shift + P → "TypeScript: Restart TS Server"For specific editors:
VS Code:
1. Open command palette (Cmd/Ctrl + Shift + P)
2. Type "TypeScript: Restart TS Server"
3. Press EnterWebStorm:
File → Invalidate Caches → Invalidate and RestartVim/Neovim with CoC:
:CocRestart### Ambient Module Declarations
Ambient declarations let you describe the shape of existing JavaScript code without implementation. This is the foundation of TypeScript's declaration files.
Basic ambient module:
// types/ambient.d.ts
declare module "some-js-library" {
export function doSomething(): void;
}Wildcard module declarations (for assets, CSS modules, etc.):
// types/assets.d.ts
declare module "*.png" {
const content: string;
export default content;
}
declare module "*.css" {
const classes: { readonly [key: string]: string };
export default classes;
}
declare module "*.svg" {
import React from "react";
export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
const src: string;
export default src;
}### Module Augmentation
Extend existing type definitions when @types packages are incomplete:
// types/express-extensions.d.ts
import "express";
declare module "express" {
// Add custom properties to Request
interface Request {
user?: {
id: string;
email: string;
};
}
}Now throughout your app:
app.get("/profile", (req, res) => {
// TypeScript knows about req.user
const userId = req.user?.id;
});### Triple-Slash Directives
Reference declaration files explicitly in your code:
/// <reference types="node" />
/// <reference path="./types/custom.d.ts" />
// Now you can use Node.js types
const buffer: Buffer = Buffer.from("hello");When to use:
- Scripts that run outside normal tsconfig.json includes
- Test files that need additional type definitions
- Ensuring specific types are always loaded
### Declaration File Resolution
TypeScript searches for .d.ts files in this order:
1. Inline with implementation: lodash/index.d.ts next to lodash/index.js
2. Package.json types field: "types": "./dist/index.d.ts"
3. @types packages: node_modules/@types/lodash/index.d.ts
4. Custom typeRoots: Directories specified in tsconfig.json
Debug resolution:
npx tsc --traceResolution | grep "lodash"Output shows exactly where TypeScript looks:
======== Resolving module 'lodash' from '/src/index.ts'. ========
Module resolution kind is not specified, using 'NodeJs'.
Loading module 'lodash' from 'node_modules' folder, target file type 'TypeScript'.
File '/node_modules/@types/lodash/index.d.ts' exist - use it as a name resolution result.
======== Module name 'lodash' was successfully resolved to '/node_modules/@types/lodash/index.d.ts'. ========### Creating Publishable Type Definitions
If you maintain a JavaScript library and want to add TypeScript support:
Option 1: Bundle types with your package
// package.json
{
"name": "my-library",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": [
"dist"
]
}Generate declarations:
// tsconfig.json
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "./dist"
}
}Option 2: Publish to DefinitelyTyped
1. Fork [DefinitelyTyped](https://github.com/DefinitelyTyped/DefinitelyTyped)
2. Create types/your-package/index.d.ts
3. Add tests in types/your-package/your-package-tests.ts
4. Submit pull request
Your types will be published as @types/your-package.
### Common Pitfalls
Mixing ESM and CommonJS types:
// WRONG - default import for CommonJS module
import express from "express";
// Error: Module has no default export
// CORRECT
import express = require("express");
// OR with esModuleInterop: true
import express from "express";Incorrect module name:
// WRONG - declaring with wrong name
declare module "my-lib" {
// ...
}
// But importing as:
import stuff from "my-lib/v2"; // Won't match!
// CORRECT - match exact import path
declare module "my-lib/v2" {
// ...
}Forgetting to include declaration files:
// tsconfig.json must include your .d.ts files
{
"include": [
"src/**/*",
"types/**/*" // Don't forget this!
]
}Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript