This error occurs when TypeScript cannot locate type definition files (.d.ts) for a package you're using. Type definitions help TypeScript understand the structure of JavaScript libraries. The fix usually involves installing the @types package for the missing library.
TypeScript error TS2688 occurs when the compiler tries to resolve type definitions for a package but cannot find them. Type definitions are .d.ts files that tell TypeScript what types, interfaces, classes, and functions a JavaScript library exports. When you import a package without type definitions, TypeScript has no way to know what methods, properties, or signatures are available. This breaks intellisense in your editor and prevents TypeScript from type-checking code that uses that library. Type definitions come from two sources: 1. **Built-in types**: Some packages (especially modern ones written in TypeScript) include their own type definitions in the "types" field of package.json 2. **@types packages**: For older JavaScript libraries without built-in types, the DefinitelyTyped project maintains separate @types packages on npm (e.g., @types/node, @types/react, @types/express) If neither is installed, TypeScript cannot find type information for the library.
First, find the exact package name from the error message. The error will show:
error TS2688: Cannot find type definition file for 'lodash'The package name is 'lodash' in this example. Look at the error message to get the exact package.
Search for the @types package on npm. Open a terminal and search:
npm search @types/lodashOr visit https://www.npmjs.com/search?q=@types%2Fyour-package
Most popular libraries have @types packages maintained by DefinitelyTyped. If you find it, note the version that matches your package version.
If the @types package exists, install it as a dev dependency:
# Install @types for the missing package
npm install --save-dev @types/lodashFor yarn:
yarn add --dev @types/lodashFor pnpm:
pnpm add -D @types/lodashFor specific version matching:
# If you have lodash v4.17.21 installed
npm install --save-dev @types/[email protected]After installation, the error should disappear immediately and your IDE's intellisense will start working.
Ensure your TypeScript configuration correctly points to node_modules/@types. Check your tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "NodeNext",
"module": "NodeNext",
"target": "ES2020"
}
}Important settings:
- moduleResolution: Should be "Node16", "NodeNext", or "Node" (never "Classic" for modern projects)
- module: Should match your runtime (Node.js uses "CommonJS" or "NodeNext")
If you have a custom typeRoots defined, ensure it includes the node_modules/@types directory:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./src/types"]
}
}Save the file and TypeScript should re-scan for type definitions.
If you're working with Node.js APIs and see errors for built-in Node.js types (fs, path, http, etc.), install @types/node:
npm install --save-dev @types/nodeMatch your Node.js version:
# If using Node.js 18
npm install --save-dev @types/node@18
# If using Node.js 20
npm install --save-dev @types/node@20After installing, you should be able to import Node.js modules with full type support:
import fs from 'fs'; // Types now available
import path from 'path'; // Types now availableFor packages without @types, you can create basic type definitions manually.
Create a file in your project (e.g., src/types/custom-package.d.ts):
// src/types/custom-package.d.ts
declare module 'custom-package' {
export function someFunction(arg: string): string;
export const someConstant: number;
export interface SomeInterface {
prop1: string;
prop2: number;
}
}Then update tsconfig.json to include your custom types directory:
{
"compilerOptions": {
"typeRoots": ["./node_modules/@types", "./src/types"]
}
}This approach is temporary—if the library later publishes types, you can remove your custom definitions.
If you need a quick fix while waiting for types to be available or created, set skipLibCheck: true in tsconfig.json:
{
"compilerOptions": {
"skipLibCheck": true,
"moduleResolution": "NodeNext",
"module": "NodeNext"
}
}What skipLibCheck does: It tells TypeScript to skip type-checking of .d.ts files, which allows you to use packages without types while maintaining type-checking for your own code.
When to use:
- Temporarily while waiting for @types package to be published
- For legacy projects with many untyped dependencies
- If type definitions have errors but you can't fix them
When NOT to use:
- As a permanent solution (you lose type safety)
- For new projects (better to use typed libraries)
- In strict type-safety environments
Note: skipLibCheck improves build speed as a side benefit since TypeScript skips checking all node_modules/@types files.
If after installing @types the error persists, clear TypeScript and npm caches:
# Clear npm cache
npm cache clean --force
# Delete node_modules and package-lock.json
rm -rf node_modules package-lock.json
# Reinstall all dependencies
npm installFor Yarn:
yarn cache clean
rm -rf node_modules yarn.lock
yarn installFor pnpm:
pnpm store prune
rm -rf node_modules pnpm-lock.yaml
pnpm installAlso restart your IDE after clearing caches so it reloads TypeScript.
Understanding DefinitelyTyped: The DefinitelyTyped project (github.com/DefinitelyTyped/DefinitelyTyped) maintains @types packages for thousands of popular JavaScript libraries. These are community-maintained and versioned separately from the original packages. When you install @types/lodash, you're installing type definitions maintained by DefinitelyTyped contributors, not by the lodash authors.
Version Matching: @types packages are versioned independently from the packages they describe. If you have [email protected] installed, you might need @types/[email protected]. Version mismatches occur when @types maintainers haven't caught up with the latest library version. Check the DefinitelyTyped GitHub to find the correct version.
Inline Types vs @types: Modern libraries include type definitions directly in their npm package. These are specified in package.json's "types" or "typings" field. Libraries like Vite, Esbuild, and axios now publish their own types, eliminating the need for @types packages. You can check if a library has built-in types by looking at its package.json.
TypeScript's Type Resolution Algorithm: TypeScript follows a specific algorithm to find type definitions: (1) Check for "types" field in package.json, (2) Look for index.d.ts in the package root, (3) Check node_modules/@types/package-name/, (4) Use automatic type acquisition (in VS Code). Understanding this order helps diagnose why types aren't found.
Automatic Type Acquisition: VS Code and some editors automatically download @types packages in the background while you type, even if they're not installed. This is why IntelliSense might work in VS Code but your builds fail—the types aren't actually in package.json. Run npm install to persist them.
Monorepo and Workspaces: In monorepo projects using yarn workspaces or pnpm workspaces, @types packages might need to be installed at the root workspace level. TypeScript uses the closest tsconfig.json and then searches up the directory tree for type definitions.
Custom Type Declarations: Beyond simple module augmentation, you can create comprehensive .d.ts files for untyped libraries. For complex libraries, use tools like dts-gen or dtslint to generate starter type definitions automatically, then refine them manually.
Performance Considerations: skipLibCheck significantly speeds up TypeScript compilation because it skips checking all .d.ts files in node_modules/@types. For large projects with many @types packages, enabling skipLibCheck can reduce build time by 20-30%. However, this only works if you trust the type definitions you're using.
Migration Strategy: When migrating a large project from skipLibCheck: true to strict type-checking, incrementally add @types packages. Start with your most-used libraries, run builds and fix type errors, then gradually add more. This prevents being overwhelmed by hundreds of type errors at once.
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