# 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.

```typescript
// 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:

```typescript
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`.

```typescript
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.

```typescript
// src/types/images.d.ts
declare module "*.png" {
  const value: string;
  export default value;
}

declare module "*.css";
```

Usage:
```typescript
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`

```typescript
// 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]]