Augmenting global/module scope from modules

Users can now declare any augmentations that they want to make, or that any other consumers already have made, to an existing module.Module augmentations look like plain old ambient module declarations (i.e. the declare module "foo" { } syntax), and are directly nested either your own modules, or in another top level ambient external module.

Furthermore, TypeScript also has the notion of global augmentations of the form declare global { }.This allows modules to augment global types such as Array if necessary.

The name of a module augmentation is resolved using the same set of rules as module specifiers in import and export declarations.The declarations in a module augmentation are merged with any existing declarations the same way they would if they were declared in the same file.

Neither module augmentations nor global augmentations can add new items to the top level scope - they can only “patch” existing declarations.

Example

Here map.ts can declare that it will internally patch the Observable type from observable.ts and add the map method to it.

  1. // observable.ts
  2. export class Observable<T> {
  3. // ...
  4. }
  1. // map.ts
  2. import { Observable } from "./observable";
  3. // Create an augmentation for "./observable"
  4. declare module "./observable" {
  5. // Augment the 'Observable' class definition with interface merging
  6. interface Observable<T> {
  7. map<U>(proj: (el: T) => U): Observable<U>;
  8. }
  9. }
  10. Observable.prototype.map = /*...*/;
  1. // consumer.ts
  2. import { Observable } from "./observable";
  3. import "./map";
  4. let o: Observable<number>;
  5. o.map(x => x.toFixed());

Similarly, the global scope can be augmented from modules using a declare global declarations:

Example
  1. // Ensure this is treated as a module.
  2. export {};
  3. declare global {
  4. interface Array<T> {
  5. mapToNumbers(): number[];
  6. }
  7. }
  8. Array.prototype.mapToNumbers = function () { /* ... */ }