C.W.K.
Stream
Lesson 03 of 05 · published

`.d.ts`: Telling TypeScript About JavaScript

~9 min · modules, d-ts, declaration-files

Level 0Curious
0 XP0/93 lessons0/23 achievements
0/100 XP to next level100 XP to go0% complete
"Declaration files describe shapes without providing implementations. They're how TypeScript types untyped JavaScript."

What a .d.ts file is

A .d.ts file contains only type information — declarations of variables, functions, classes, modules. No function bodies, no class bodies, no values. The compiler reads them to understand what types a JavaScript module exports.

Most libraries on npm ship their own .d.ts files alongside their .js. If they don't, the community-maintained @types/library-name package usually provides them. The TypeScript compiler looks for both automatically.

Writing your own

When you use an untyped JavaScript library, you can write a .d.ts file to tell TypeScript what it exports. Place it anywhere tsconfig.json's include covers — typically at the project root or in a types/ directory.

// custom-lib.d.ts
declare module 'custom-lib' {
  export function doThing(x: number): string;
  export interface Config { host: string }
}

Now import { doThing } from 'custom-lib' compiles with proper types, even though the library has no embedded types.

The TypeScript standard library

The types for Array, Map, Set, Promise, fetch, document, etc., all live in .d.ts files inside node_modules/typescript/lib/. lib.es5.d.ts for ES5; lib.dom.d.ts for browsers; lib.es2022.d.ts for newer ES features. The tsconfig lib option controls which of these get loaded.

.d.ts files are how TypeScript stays interoperable with JavaScript without forcing the JavaScript to be rewritten. Any module — typed or not — can be given types by writing a declaration file.

Code

Writing a .d.ts for an untyped module·typescript
// my-lib.d.ts — declares an untyped module.
declare module 'untyped-lib' {
  export function add(a: number, b: number): number;
  export const VERSION: string;
  export default class Thing {
    constructor(name: string);
    getName(): string;
  }
}

// consumer.ts — now uses the typed module.
import Thing, { add, VERSION } from 'untyped-lib';

add(1, 2);            // ✅ typed
Thing;                // ✅ class
VERSION;              // ✅ string

// Declaration files can also declare globals.
declare global {
  interface Window {
    appConfig: { apiBase: string };
  }
}
window.appConfig.apiBase;   // ✅ — now typed everywhere

External links

Exercise

Find a small JavaScript library that doesn't have types (or imagine one). Write a .d.ts for it that declares two functions and one constant. Import them from your TypeScript code and confirm autocomplete works.
Hint
The declare module 'name' block tells TypeScript 'this module has these exports.' Without a body for the functions — just signatures.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.