Skip to main content

Type Declaration Files

Type declaration files (.d.ts) are a fundamental part of TypeScript that provide type information for JavaScript code. Let's learn how to work with them!

What are Declaration Files?

Declaration files (with the .d.ts extension) contain type information for JavaScript code. They're like contracts that describe the shape of JavaScript code without providing the implementation.

// example.d.ts
declare function greet(name: string): string;
declare const version: string;

declare class User {
name: string;
age: number;
constructor(name: string, age: number);
sayHello(): void;
}

Creating Declaration Files

For Your Own Code

When you write TypeScript code, the compiler can automatically generate declaration files:

{
"compilerOptions": {
"declaration": true, // Generate .d.ts files
"declarationMap": true // Generate sourcemaps for .d.ts files
}
}

For JavaScript Libraries

When writing declarations for JavaScript libraries:

// library.d.ts
declare namespace MyLibrary {
function makeGreeting(name: string): string;
function numberOfGreetings: number;
}

declare module "my-library" {
export = MyLibrary;
}

Ambient Declarations

Ambient declarations tell TypeScript that the implementation exists elsewhere:

// globals.d.ts
declare const process: {
env: {
NODE_ENV: 'development' | 'production';
[key: string]: string | undefined;
}
};

declare global {
interface Window {
myGlobalFunction(): void;
}
}

Using Type Definitions

From DefinitelyTyped

Many libraries have type definitions available through DefinitelyTyped:

npm install --save-dev @types/lodash

Then use them in your code:

import { map, reduce } from 'lodash';
// TypeScript now knows the types!

Writing Your Own

// custom.d.ts
declare module "*.json" {
const value: any;
export default value;
}

declare module "*.svg" {
const content: string;
export default content;
}

Module Augmentation

You can extend existing modules with new functionality:

// moment-extension.d.ts
import 'moment';

declare module 'moment' {
interface Moment {
customFormat(): string;
}
}

Best Practices

  1. Triple-Slash Directives

    /// <reference path="./other-file.d.ts" />
    /// <reference types="node" />
  2. Module Declaration Patterns

    // UMD modules
    declare module 'my-lib' {
    export function doSomething(): void;
    export default class MyClass {}
    }
  3. Type Definition Structure

    // Good organization
    declare namespace MyLib {
    interface Options {
    // ...
    }

    class MainClass {
    // ...
    }

    function helper(): void;
    }
  4. Documentation Comments

    /**
    * Represents a book in the library
    * @param title - The title of the book
    * @param author - The author of the book
    */
    declare class Book {
    constructor(title: string, author: string);
    }

Common Patterns

  1. Function Overloads

    declare function createElement(tag: 'div'): HTMLDivElement;
    declare function createElement(tag: 'span'): HTMLSpanElement;
    declare function createElement(tag: string): HTMLElement;
  2. Generic Types

    declare class Container<T> {
    value: T;
    setValue(value: T): void;
    }
  3. Conditional Types

    declare type ArrayType<T> = T extends any[] 
    ? T[number]
    : never;

Remember that good type declarations make your code more maintainable and provide better IDE support. Take time to write clear and accurate type definitions!