`.d.ts` — Types Without Implementation
Declaration Files
A `.d.ts` file describes the shape of a module without shipping any runtime code. The whole `@types/...` ecosystem is `.d.ts`.
What you'll learn
- Read a `.d.ts` file
- Install `@types/...` for an untyped library
- Know when to write your own
A .d.ts file is a declaration file — it describes types
without containing implementation. The whole @types/ Node
ecosystem is .d.ts files.
What’s Inside
// lodash.d.ts (excerpt — simplified)
declare module "lodash" {
export function chunk<T>(array: T[], size: number): T[][];
export function debounce<F extends Function>(fn: F, ms: number): F;
} declare module "lodash" tells TS “here are the types for the
lodash package.” No function bodies — only signatures.
Installing Library Types
Most popular libraries ship their own types built-in (Zod, Vite,
React Router). Some don’t — then you install from
DefinitelyTyped:
npm install --save-dev @types/lodash After that, import _ from "lodash" is fully typed.
Writing Your Own
For an untyped library with no @types/... package:
// src/types/some-lib.d.ts
declare module "some-lib" {
export function doThing(input: string): number;
export const VERSION: string;
} A two-line shim is often enough to satisfy the compiler. Type only what you actually use.
Auto-Generated .d.ts
When you build a TS library for publishing, tsc can emit .d.ts
files alongside the JS:
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "dist"
}
} Publishing a TS library means publishing JS + .d.ts (so JS
consumers get the runtime, TS consumers get the types).
Reading the DOM Lib
Almost every type you know — Element, HTMLInputElement,
fetch, Response — lives in lib.dom.d.ts, shipped with TS.
Open it in your editor (F12 on fetch) and read it; you’ll
learn an enormous amount about how the DOM is actually typed.
Up Next
Ambient types — declare at the top level for things that exist
globally.