100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
TypeScript

Declaration Files (.d.ts) in TypeScript

How .d.ts files describe the shape of JavaScript code for the TypeScript compiler, including DefinitelyTyped (@types) packages.

Modules & ToolingIntermediate11 min readJul 8, 2026
Analogies

1. Introduction

A declaration file, always ending in .d.ts, describes the types of an existing JavaScript API — its variables, functions, classes, and modules — without containing any executable implementation code. Declaration files let the TypeScript compiler type-check and autocomplete calls into plain JavaScript libraries, your own hand-written JS, or compiled output, as if that code had been written in TypeScript.

🏏

Cricket analogy: A player's scorecard summary lists batting order and stats without showing the actual shots played, just as a .d.ts file describes a function's variables and signatures without any executable implementation code.

TypeScript itself generates .d.ts files automatically for your own .ts source when the declaration compiler option is enabled, which is essential when publishing a TypeScript library so consumers get type information without needing your original source. For third-party JavaScript packages that don't ship their own types, the community-maintained DefinitelyTyped project distributes declaration files as @types/* npm packages.

🏏

Cricket analogy: When a coach compiles a young batsman's technique manual straight from his net sessions it's auto-generated; the declaration option similarly auto-generates .d.ts files from your .ts source when publishing a library.

2. Syntax

typescript
// mathLib.js (plain JavaScript library, no types)
function add(a, b) {
  return a + b;
}
module.exports = { add };

// mathLib.d.ts — hand-written declaration file
declare function add(a: number, b: number): number;

export { add };

// Ambient global declaration (for a script with no module system)
declare global {
  interface Window {
    myLibVersion: string;
  }
}

// consumer.ts
import { add } from "./mathLib";
const sum: number = add(2, 3); // type-checked even though mathLib.js has no types

3. Explanation

Declaration files (.d.ts) provide type information for plain JS libraries without containing actual implementation code — every statement uses declare (or is implicitly ambient inside a .d.ts file) to describe a shape rather than produce runtime output. When you import from a module that has an accompanying .d.ts file (either colocated, bundled in the package's types/typings field, or resolved from node_modules/@types/<package>), TypeScript merges the declared types onto the actual JavaScript implementation so calls are checked at compile time but execute the real, untyped JS at runtime.

🏏

Cricket analogy: A stadium's electronic scoreboard only displays runs and wickets, never running the match itself; likewise every statement in a .d.ts file uses declare to describe a shape while the real JS engine plays out at runtime.

DefinitelyTyped (@types/) packages provide community-maintained type declarations for thousands of JavaScript libraries that don't publish their own types — installing npm install --save-dev @types/lodash gives the compiler everything it needs to type-check calls into the untyped lodash package. Libraries that ship their own types (common for packages authored in TypeScript) declare this via a types or typings field in their package.json, so no separate @types package is needed.

🏏

Cricket analogy: A domestic academy publishes free coaching notes for uncapped players who lack a personal manual, much like npm install --save-dev @types/lodash supplies compiler-ready notes for the untyped lodash package.

You can generate .d.ts files automatically from your own TypeScript source by setting "declaration": true in tsconfig.json — this is required practice before publishing any TypeScript library to npm so consumers (including plain JavaScript consumers using an editor with TS language service support) get full autocomplete and type checking.

Gotcha: an @types/* package version is independent of the actual library's version, and they can drift out of sync — installing a newer version of a JS library without updating its matching @types package (or vice versa) can produce type errors for APIs that changed, or worse, silently wrong types that don't reflect real runtime behavior. Always check that @types/<pkg> version ranges correspond to the installed library version.

4. Example

typescript
// events.d.ts — describing a small pub/sub JS library
declare module "tiny-events" {
  export type Listener = (payload: unknown) => void;

  export class EventBus {
    on(event: string, listener: Listener): void;
    off(event: string, listener: Listener): void;
    emit(event: string, payload?: unknown): void;
  }
}

// app.ts
import { EventBus } from "tiny-events";

const bus = new EventBus();
bus.on("greet", (payload) => console.log("Received:", payload));
bus.emit("greet", { name: "Ada" });

5. Output

text
Compiling app.ts succeeds with full type checking on EventBus.on/off/emit even though tiny-events is plain, untyped JavaScript at runtime.

At runtime (after compiling and running with the real tiny-events JS implementation loaded):
Received: { name: 'Ada' }

The events.d.ts file itself produces zero runtime output  it is stripped entirely during compilation and exists purely to inform the type checker and editor tooling.

6. Key Takeaways

  • A .d.ts file describes types only — it contains no executable implementation code and produces no runtime output.
  • Enable "declaration": true in tsconfig.json to auto-generate .d.ts files when publishing a TypeScript library.
  • DefinitelyTyped's @types/* packages supply community-maintained types for JavaScript libraries that don't ship their own.
  • Libraries can self-declare types via the types/typings field in package.json instead of relying on a separate @types package.
  • declare module "name" { ... } describes the shape of an external module so it can be imported with full type safety.
  • @types package versions can drift from the actual library version, causing type mismatches — verify compatibility when upgrading.

Practice what you learned

Was this page helpful?

Topics covered

#TypeScript#TypeScriptProgrammingStudyNotes#Programming#DeclarationFilesDTsInTypeScript#Declaration#Files#Syntax#Explanation#StudyNotes#SkillVeris