Declaration files (.d.ts) provide type information for JavaScript code without implementations — they enable TypeScript to type-check against libraries, ambient declarations describe globals like window extensions, and module augmentation extends third-party package types.
Contain only type declarations (no runtime code) — describe function signatures, interfaces, and constants using the declare keyword.
Community-maintained type packages for JavaScript libraries. Many modern libraries now ship built-in .d.ts files, making @types unnecessary.
Describe globals that exist at runtime but aren't imported — global variables, Window extensions, process.env typing.
Extend third-party package types using declare module and declaration merging — commonly used to add properties to Express Request or extend library interfaces.
Declaration files are TypeScript's mechanism for describing the types of JavaScript code that doesn't have TypeScript source. They contain only type information — no runtime code, no implementations, no expressions that produce values.
A .d.ts file contains type declarations: function signatures, interface definitions, class shapes, and constant types. The compiler uses these to type-check code that references the described JavaScript. When you import from a library, TypeScript looks for matching .d.ts files to understand the library's API.
// math-utils.d.ts
export declare function add(a: number, b: number): number;
export declare function multiply(a: number, b: number): number;
export declare const PI: number;The declare keyword tells TypeScript "this exists at runtime, but I'm only describing its type." You can't include implementation code in a declaration file.
For JavaScript libraries without built-in types, the DefinitelyTyped repository provides community-maintained declaration files. Install them via @types/ packages: npm install @types/lodash. TypeScript automatically picks up @types packages from node_modules/@types/.
Many libraries now ship their own declaration files ("built-in types") by including .d.ts files in the npm package and setting types or typings in package.json. When a library has built-in types, you don't need @types.
For TypeScript projects, the compiler generates .d.ts files automatically with declaration: true in tsconfig. This is how TypeScript libraries ship types — you compile your .ts source to .js + .d.ts output. The declaration file exposes your public API types without exposing implementation details.
declarationMap: true generates source maps from .d.ts back to .ts source, enabling "Go to Definition" to jump to the original TypeScript source rather than the declaration file.
Ambient declarations describe types for things that exist globally in the runtime environment but aren't imported as modules. Common use cases:
declare const __DEV__: boolean; describes a build-time constantdeclare global { interface Window { analytics: Analytics } } adds properties to the Window interfaceProcessEnv to type process.env valuesAmbient declarations go in .d.ts files that are included in your project (via include in tsconfig or a /// <reference> directive).
Module augmentation lets you add types to existing packages:
// Extend Express Request
declare module 'express' {
interface Request {
userId?: string;
sessionId?: string;
}
}This uses declaration merging — TypeScript merges your augmented interface with the library's existing Request interface. The augmented file must be a module (have at least one import/export) for this to work.
For non-JavaScript imports that bundlers handle (CSS, images, SVG), declare wildcard modules:
declare module '*.css' { const content: Record<string, string>; export default content; }
declare module '*.svg' { const content: React.FC<React.SVGProps<SVGSVGElement>>; export default content; }Declaration files (.d.ts) contain only type information — no runtime code. They describe JavaScript APIs for TypeScript's type checker. @types packages provide community types for untyped libraries. Module augmentation extends third-party package types using declaration merging. declare means "this exists at runtime, I'm just describing the type."
Fun Fact
DefinitelyTyped is one of the largest open-source repositories on GitHub with over 8,000 type packages maintained by the community. It receives thousands of pull requests per month. The @types packages are auto-published by a bot — human maintainers review the PRs, but the npm publishing pipeline is fully automated.