TypeScript's `declare`: A Promise to the Compiler
`declare` promises the TypeScript compiler a value exists, even if it can't see the source. This lets you use untyped JavaScript libraries or browser APIs without errors.
WHY IT EXISTS TypeScript needs to know the types of everything it interacts with to provide safety. But many projects use code that TypeScript doesn't compile directly, like a browser's window object or a JavaScript library loaded via a <script> tag. The declare keyword was created to bridge this gap, allowing you to inform the compiler about the types of this 'ambient' code.
THE MENTAL MODEL Think of declare as writing a contract for the TypeScript compiler. You're saying, "Compiler, I promise you that at runtime, there will be a global variable named myLib with these specific functions and properties. Don't worry about where it comes from; just trust me and let me use it as if it were typed." The compiler then uses this contract for type-checking but generates no actual code for the declaration itself.
HOW IT WORKS The declare keyword tells the compiler about a type, variable, function, or namespace without providing an implementation. These declarations are typically placed in special files with a .d.ts extension. For example, declare function getWidget(id: number): Widget; tells TypeScript that a function named getWidget exists globally. declare namespace myLib { ... } describes an object with properties. The TypeScript compiler reads these .d.ts files and makes the types available project-wide, but it emits zero JavaScript for them. They are purely for static analysis.
WHEN TO USE IT Use declare when you are consuming JavaScript code from a TypeScript project and that code does not have its own type definitions. Three common scenarios are: first, interacting with browser-specific APIs not in the standard types (e.g., window.myCustomApi); second, using older JavaScript libraries included via a <script> tag; and third, gradually migrating a JavaScript project to TypeScript by describing existing JS modules so new TS code can call them safely.
WHEN NOT TO USE IT Do not use declare for code you are writing within your TypeScript project. If you're writing a new function, class, or variable, just write it normally with TypeScript syntax. The compiler will infer or check its type. Using declare for your own new code is a sign you're fighting the compiler; it's meant for describing external, already-existing code.
ONE CANONICAL EXAMPLE Imagine you include a legacy analytics library via a <script> tag, which creates a global object analytics. To use it safely in TypeScript, you'd create a file like global.d.ts and write: declare namespace analytics { function track(eventName: string, properties: object): void; let user: string; } Now, in any .ts file, you can call analytics.track('page_view', { url: '/' }); and TypeScript will know the function's signature, preventing typos and incorrect usage.
Read the original → typescriptlang.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.