Skip to content
CodeMorph
Learn

Types for third-party packages

Where types for your dependencies come from, how to install them, and what to do when a package has none.

Beginner2 min readUpdated 11 October 2026

Your code is only as well typed as the packages it uses. Here's how to get types for every dependency, and what to do when there aren't any.

Packages that ship their own types

Many packages include type definitions in their own published files. You'll see a types or typings field in their package.json, or .d.ts files next to the JavaScript. There's nothing to install: imports are typed automatically.

Packages typed by the community

For packages without built-in types, the community maintains definitions in DefinitelyTyped, published under the @types scope:

npm install --save-dev @types/express @types/lodash

The @types package name mirrors the original. Scoped packages use a double underscore: types for @babel/core are in @types/babel__core.

Keep @types versions roughly in step with the package itself; a mismatch can mean types for an API that doesn't match the version you run.

Node.js itself

Node's built-in modules are typed by @types/node. Install the major version that matches your runtime:

npm install --save-dev @types/node@22

Packages with no types at all

If neither the package nor DefinitelyTyped has types, declare the module yourself. The quickest option makes it any, and gets you unblocked:

src/types/vendor.d.ts
declare module "legacy-lib";

A better option describes just the parts you use:

src/types/legacy-lib.d.ts
declare module "legacy-lib" {
  export function parse(input: string): Record<string, string>;
  export const version: string;
}

Make sure the folder is covered by include in your tsconfig.json.

Adding to existing types

Sometimes a package's types are fine but your app adds something, such as a user on Express requests. Use declaration merging instead of editing the package:

src/types/express.d.ts
declare global {
  namespace Express {
    interface Request {
      user?: { id: string; email: string };
    }
  }
}
export {};

When types are wrong

  • Check you're on the latest @types version for your package version.
  • Narrow the type at your boundary: wrap the call in a small typed function so the rest of your code never sees the bad type.
  • As a last resort, use // @ts-expect-error with a comment explaining why, so it fails loudly once the upstream types are fixed.

skipLibCheck

"skipLibCheck": true tells TypeScript not to check .d.ts files in your dependencies. It speeds up type-checking and avoids errors in code you don't control. Your own code is still fully checked.

How CodeMorph treats packages

During Scan & Plan, every import of a package is checked against your package.json. Imports of packages you haven't declared are recorded as unresolved, so missing dependencies show up before you start converting.

Next guideKeeping TypeScript green in CI

Let CodeMorph do the heavy lifting.

Download the beta, open a project and see your migration plan in under a minute.