๐ŸŽ“ A1Learner
๐Ÿ”
0 of 37 lessons completed

TypeScript Ambient Modules

An ambient module declaration gives a name pattern a type without any implementation file. Imports that match the pattern are checked against the declared type, and imports that match nothing are refused.

The assets.d.ts file

The declaration file gives style imports a record of class names and image imports a string path. A shorthand declaration for chart-widget sits at the end with no members at all.

declare module '*.css' {
  const classes: { [key: string]: string };
  export default classes;
}

declare module '*.png' {
  const src: string;
  export default src;
}

declare module 'chart-widget';

Importing declared patterns

The first line pulls the declaration file into the program. Both imports match a wildcard, so each binding gets its declared type and the witness values print.

export {} from './assets';
import type styles from './site.css';
import type logo from './logo.png';

const bannerClass: typeof styles = { banner: 'banner-main' };
const logoPath: typeof logo = 'logo.png';

console.log(bannerClass.banner);
console.log(logoPath);

A shorthand module accepts any shape

The shorthand declaration names no members, so the imported binding has type any. A value of any shape is accepted for it.

export {} from './assets';
import type widget from 'chart-widget';

const config: typeof widget = { mode: 'fast', retries: 3 };
console.log(config.mode);
console.log(config.retries);

An undeclared pattern is refused

No declaration matches a .txt import, so the compiler refuses the program. The refusal below is the real compiler output for this code.

export {} from './assets';
import type notes from './notes.txt';

const draftText: typeof notes = 'draft';
console.log(draftText);

Example

export {} from './assets';
import type styles from './theme.css';
import type icon from './icon.png';
import type widget from 'chart-widget';

const themeClass: typeof styles = { panel: 'panel-dark' };
const iconPath: typeof icon = 'icon.png';
const widgetMode: typeof widget = 'compact';

console.log(themeClass.panel);
console.log(iconPath);
console.log(widgetMode);

Key points

  • A wildcard pattern such as *.css matches every import path that ends with that suffix.
  • The declaration lives in a declaration file and holds types only, with no code that runs.
  • A shorthand ambient module declares only a name, so every import from it gets the type any.
  • Asset imports in this lesson travel as type-only imports, so no asset file is loaded at runtime.

In this example, two wildcard imports and one shorthand import supply their declared types, and plain witness values print in order.

Note

A bundler or loader supplies the real asset at build time in a real project, while the declaration supplies its type.

Try it Yourself

Edit the code, then press Run.

Running is simulated ยท TypeScript Playground

Exercise

What does a wildcard ambient declaration give an import?