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
-
Triple-Slash Directives
/// <reference path="./other-file.d.ts" />
/// <reference types="node" /> -
Module Declaration Patterns
// UMD modules
declare module 'my-lib' {
export function doSomething(): void;
export default class MyClass {}
} -
Type Definition Structure
// Good organization
declare namespace MyLib {
interface Options {
// ...
}
class MainClass {
// ...
}
function helper(): void;
} -
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
-
Function Overloads
declare function createElement(tag: 'div'): HTMLDivElement;
declare function createElement(tag: 'span'): HTMLSpanElement;
declare function createElement(tag: string): HTMLElement; -
Generic Types
declare class Container<T> {
value: T;
setValue(value: T): void;
} -
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!