declare and . d. ts files
Describing the types of something that exists outside your TypeScript code: global variables, JavaScript libraries, and modules.
Example
#// src/types/globals.d.ts
declare const APP_VERSION: string
declare function trackEvent(name: string, data?: Record<string, unknown>): void
// src/lesson.ts
trackEvent('lesson_completed', { lesson: 'flexbox', version: APP_VERSION })
trackEvent(42)
// Error: Argument of type 'number' is not assignable to parameter of type 'string'.The bundler inserts the value of APP_VERSION during the build, and the trackEvent function is added by an analytics script included on the page. The compiler only knows about them because of the declarations.
Definition and usage
#The declare keyword tells the compiler that something exists, even though it wasn’t defined in this spot: a variable injected by another script on the page, a function from a library written in JavaScript, or an entire module. The declaration only describes the type and disappears after compilation, it creates no code.
Files with the .d.ts extension contain only descriptions like that, with no implementation. The compiler generates them from your code with the declaration option, and library authors bundle them with their npm packages. For packages with no types of their own, there are @types/… packages from the DefinitelyTyped repository, for example @types/lodash.
In your own project, a .d.ts file comes in handy for describing global variables, extending built-in types with declare global, and importing files that aren’t code, for example declare module "*.svg". The file has to be covered by include in tsconfig.json, otherwise the compiler won’t see it.
Syntax
#declare const name: type
declare function name(param: type): type
declare module "package" { … }
declare global { … }Kinds of declarations
#declare const
A global variable, for example one injected by a bundler or a script included on the page. Instead ofconstyou can useletorvar.declare function
A function available globally. You can give several signatures, just like with overloads.declare class
A class defined outside TypeScript, for example in an older library.declare module
The types of an entire module: an npm package ("legacy-charts") or a file pattern ("*.svg").declare global
Adds declarations to the global scope from inside a module, for example a new field onWindow.
More examples
#// src/types/legacy-charts.d.ts
declare module 'legacy-charts' {
interface ChartOptions {
title: string
values: number[]
color?: string
}
export default function drawChart(element: HTMLElement, options: ChartOptions): void
}
// src/progress.ts
import drawChart from 'legacy-charts'
drawChart(document.body, { title: 'Progress' })
// Error: Argument of type '{ title: string; }' is not assignable to parameter of type 'ChartOptions'.
// Property 'values' is missing in type '{ title: string; }' but required in type 'ChartOptions'.// src/types/window.d.ts
export {}
declare global {
interface Window {
dataLayer: unknown[]
}
}
// any file in the project
window.dataLayer.push({ event: 'signup' })The export {} line turns the file into a module. Without it, the compiler reports “Augmentations for the global scope can only be directly nested in external modules or ambient module declarations.”
Good practices
#- Before writing your own types for a package, check whether a
@types/package-namepackage exists. The message “Could not find a declaration file for module” usually suggests it on its own. - The shorthand
declare module "package";with no body silences the error, but then everything from the module gets the typeany. Treat it as a temporary fix. declaredoesn’t create anything. If the variable truly doesn’t exist in the running program, the compilation passes, and the program stops with an “is not defined” error.
Related entries
#Spotted a mistake or missing an example? Write to us.