JavaScript > TypeScript > Advanced TypeScript > Declaration files

Creating and Using TypeScript Declaration Files

This example demonstrates how to create and use TypeScript declaration files (.d.ts) to provide type information for JavaScript libraries or modules.

What are Declaration Files?

Declaration files are TypeScript files that contain only type declarations. They tell the TypeScript compiler about the shape of existing JavaScript code. This allows you to use JavaScript libraries in your TypeScript projects and get type checking, autocompletion, and other benefits without having to rewrite the JavaScript code in TypeScript.

Creating a Declaration File (my-library.d.ts)

This code defines a declaration file for a hypothetical JavaScript library called 'my-library'. It declares a module with the same name. Inside the module, it declares a function `myAwesomeFunction`, an interface `MyOptions`, and a class `MyClass`. The declarations specify the types of the function's arguments and return value, as well as the properties of the interface and the methods of the class.

// my-library.d.ts

declare module 'my-library' {
  export function myAwesomeFunction(name: string): string;
  export interface MyOptions {
    option1: boolean;
    option2: number;
  }
  export class MyClass {
      constructor(options: MyOptions);
      doSomething(): void;
  }
}

Explanation of the Declaration File

  • declare module 'my-library': This tells TypeScript that we are declaring a module named 'my-library'. Modules are used to organize code and prevent naming conflicts.
  • export function myAwesomeFunction(name: string): string;: This declares a function named `myAwesomeFunction` that takes a string argument named `name` and returns a string. The `export` keyword makes the function available to other modules.
  • export interface MyOptions {: This declares an interface named `MyOptions` with two properties: `option1` (boolean) and `option2` (number). Interfaces define the shape of an object.
  • export class MyClass {: This declares a class named `MyClass` with a constructor that takes an `MyOptions` object as an argument and a method called `doSomething`.

Using the Declaration File in a TypeScript Project

This TypeScript code imports the declarations from 'my-library'. Thanks to the declaration file, TypeScript knows the types of `myAwesomeFunction`, `MyOptions`, and `MyClass`, and provides type checking and autocompletion. If you make a mistake, like passing a number to `myAwesomeFunction`, the TypeScript compiler will flag it as an error.

// my-typescript-file.ts

import { myAwesomeFunction, MyOptions, MyClass } from 'my-library';

const result = myAwesomeFunction('TypeScript');
console.log(result);

const options: MyOptions = {
  option1: true,
  option2: 123
};

const myInstance = new MyClass(options);
myInstance.doSomething();

Real-Life Use Case

Imagine you're using a popular JavaScript charting library that doesn't have TypeScript definitions. You can create a declaration file to describe the library's API, allowing you to use it safely and effectively in your TypeScript project. This avoids having to use `any` types and losing type safety.

Best Practices

  • Keep Declaration Files Up-to-Date: As the JavaScript library evolves, ensure your declaration file reflects the changes.
  • Use DefinitelyTyped: Before writing your own declaration file, check DefinitelyTyped (a repository of high-quality TypeScript definitions for many popular JavaScript libraries). Someone may have already created and maintained one for you.
  • Be Precise: Provide accurate and complete type information in your declaration files. Inaccurate or incomplete declarations can lead to runtime errors and defeat the purpose of using TypeScript.

When to use them

Declaration files are used when:

  • You want to use a JavaScript library in your TypeScript project.
  • You want to provide type information for your own JavaScript code.
  • You want to describe the API of a module without implementing it in TypeScript.

Alternatives

  • @ts-check in JavaScript files: Can provide basic type checking in plain JavaScript without TypeScript, but less powerful than declaration files.
  • JSDoc annotations: Can be used in JavaScript files to provide type information, but can be verbose and harder to maintain than declaration files.

Pros

  • Provides type safety when using JavaScript libraries in TypeScript.
  • Enables autocompletion and other IDE features.
  • Improves code maintainability and reduces runtime errors.

Cons

  • Requires effort to create and maintain declaration files.
  • Can be complex to write for large or complex JavaScript libraries.

FAQ

  • What happens if I don't have a declaration file for a JavaScript library?

    TypeScript will not have any type information about the library, and you'll likely have to use the `any` type, which defeats the purpose of using TypeScript for type safety.
  • How does TypeScript find declaration files?

    TypeScript looks for declaration files in the same directory as the JavaScript file, and in directories specified in the `typeRoots` and `types` compiler options in the `tsconfig.json` file.