2 min read

TypeScript Ambient Modules and Global Augmentation

TypeScript provides mechanisms to describe code that exists at runtime but isn't strictly typed in your source files. This is essential for working with third-party JavaScript libraries, assets, or global variables.

1. Ambient Modules

Ambient modules are used to declare the shape of a module that doesn't have its own type definitions. They are typically placed in a .d.ts file.

A. Typing an Untyped Library

If you import a library like my-legacy-lib that doesn't have types, TypeScript will error. You can fix this by declaring the module.

// src/types/my-legacy-lib.d.ts
declare module "my-legacy-lib" {
  export function doSomething(arg: string): void;
  export const version: number;
}

Now you can import it without errors:

import { doSomething } from "my-legacy-lib";
doSomething("hello");

B. Shorthand Ambient Modules

If you don't want to write out all the types immediately, you can use a shorthand. This treats everything imported from the module as any.

declare module "my-legacy-lib";

C. Wildcard Modules (File Loaders)

This is commonly used in Webpack/Vite projects to allow importing non-code assets like images or CSS.

// src/types/images.d.ts
declare module "*.png" {
  const value: string;
  export default value;
}

declare module "*.css";

Usage:

import logo from "./logo.png"; // logo is string

2. Global Augmentation

Sometimes you need to add properties to the global scope (e.g., window in browsers or global in Node.js). Since TypeScript assumes the global scope is fixed, you need to use Global Augmentation.

Rules

  1. The file containing the augmentation must be a module. This means it must have at least one import or export. If it doesn't, add export {}; at the top.
  2. Use the declare global block.

Example: Adding to window

// src/types/global.d.ts
export {}; // Make this a module

declare global {
  interface Window {
    __INITIAL_DATA__: any;
    analytics: {
      track(event: string): void;
    };
  }
}

// Usage in app.ts
window.analytics.track("Page View");

3. Difference from Module Augmentation

  • Ambient Modules (declare module "foo"): Used when the module "foo" does not exist in TypeScript's eyes (no types available). You are creating it from scratch.
  • Module Augmentation (declare module "./foo"): Used when the module already exists (has types), but you want to add extra properties to it (merging).

programming/javascript/typescript/typescript programming/javascript/typescript/declaration-files