TypeScript Declaration Files
One of TypeScript's core advantages is its ability to seamlessly work with existing JavaScript libraries and code. However, standard JavaScript files (.js) don't contain type information themselves. To help the TypeScript compiler understand the types, function signatures, and object shapes of these JavaScript libraries, we use declaration files.
Declaration files have a .d.ts extension and don't contain any implementation code (function bodies, variable initial values, etc.), only type definitions.
Why Do We Need Declaration Files?
When you use a popular JavaScript library (like jQuery, Lodash, React), you want to get type checking and intelligent auto-completion when calling its functions in TypeScript code. Declaration files are the bridge that provides this type information.
Without declaration files:
// Suppose we're using 'my-library' without a declaration file
import { doSomething } from 'my-library';
// TypeScript compiler will error because it doesn't know what 'my-library' is,
// nor does it know about the doSomething function's existence and parameter types.
// Error: Cannot find module 'my-library'.
doSomething(123);With declaration files:
// my-library.d.ts (declaration file)
declare module 'my-library' {
export function doSomething(value: number): string;
}// app.ts (your code)
import { doSomething } from 'my-library';
doSomething(123); // OK
// doSomething("hello"); // Error: Argument of type 'string' is not assignable to parameter of type 'number'.How to Get Declaration Files?
For most popular JavaScript libraries, you don't need to manually write declaration files. The community has already done this work for us.
1. Libraries with Built-in Declaration Files
Many modern libraries already include their own .d.ts declaration files when published. When you install these libraries through npm, the declaration files are automatically recognized by TypeScript.
2. DefinitelyTyped Project
For JavaScript libraries that don't include type declarations themselves, there's a massive community project called DefinitelyTyped that provides high-quality declaration files for thousands of libraries.
These declaration files are all published under the @types scope on npm. You just need to install the corresponding @types package.
For example, to install declaration files for the lodash library, simply run:
npm install --save-dev @types/lodashAfter installation, you can use lodash in your TypeScript project just like a native TypeScript library.
Writing Your Own Declaration Files
In some cases, you may need to write declaration files for your own JavaScript code or a third-party library that doesn't have type definitions.
The declare Keyword
The declare keyword is used to tell TypeScript that a variable, function, or module exists and has a specific type, but its actual implementation is elsewhere (usually in a .js file).
Declaring a global variable:
// global.d.ts
declare const MY_GLOBAL_VARIABLE: string;Declaring a module:
// my-untyped-module.d.ts
declare module 'my-untyped-module' {
export function someFunction(arg: string): boolean;
export const someConstant: number;
}Declaration File Structure
- Global declarations: If your JavaScript code runs in the global scope (for example, included via a
<script>tag), you can directly usedeclare var,declare function, etc. in the.d.tsfile. - Modular declarations: If your JavaScript code is a module, you should use the
declare module 'module-name' { ... }syntax.
Writing high-quality declaration files can be complex and requires a deep understanding of TypeScript's type system. However, for most developers, the main task is consuming (rather than creating) declaration files.
Related Configuration in tsconfig.json
"noImplicitAny": true: This is a recommended option to enable. When it'strue, if TypeScript cannot infer a variable's type and there's no corresponding declaration file, it will error rather than implicitly treating it asanytype. This helps you discover places in your project that lack type definitions."typeRoots"and"types": These options let you control where the compiler looks for declaration files. Typically, you don't need to manually configure them.