Declaration Files 📜
.d.ts files describe the shape of JS libraries so editors know their APIs—think of them as subtitles for runtime code.
When You Need Them 🤔
- Shipping a JS library but want TypeScript consumers to get types.
- Wrapping third-party globals (
window.payments?). - Augmenting modules that lack a type definition.
Anatomy of .d.ts 🧬
// types/logger.d.ts
export interface LoggerOptions {
level?: "info" | "warn" | "error";
}
export function createLogger(options?: LoggerOptions): Logger;- No implementations—only signatures.
- Use
declarekeyword for ambient/global definitions.
declare global {
interface Window {
analytics?: AnalyticsClient;
}
}Remember to reference the file (via types array or include).
Module Augmentation ➕
Add fields to existing modules.
declare module "express" {
interface Request {
user?: { id: string };
}
}- Place inside
.d.tsthat lives somewhere TypeScript can find. - Great for extending frameworks (Express, Fastify, etc.).
Publishing Types 📦
- Include
.d.tsfiles in npm package. - Point
package.jsonto them:
{
"types": "dist/index.d.ts"
}- Generate automatically with
tsc --emitDeclarationOnly.
DefinitelyTyped / @types 🎁
- Massive community repo of
.d.tsfiles. - Install via
npm i -D @types/lodash(package name matches library). - For scoped packages:
@types/react-routeror@types/express-serve-static-core.
Analogy: DefinitelyTyped is a public library of subtitles someone already wrote for you.
Tips ✅
- Keep declarations versioned alongside runtime code.
- Use
declare namespacefor global script builds. - Add tests with
tsdortypescript-testto ensure declarations match behavior. - Avoid ambient globals when modules will do—namespaces can collide.
Good declarations make your library feel first-class in any editor. ✨
Last updated on