Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why do ambient declarations use namespace and module?

I noticed that many ambient declaration files declare a namespace and a module that merely exports the namespace, usually using some gymnastics that I don't really understand. For example, in react.d.ts you see this:

declare namespace __React {

    ... entire API of the react library ...

}

declare module "react" {
    export = __React;
}
  1. Why both a namespace and a module? Why not just declare the module with the library API inside it?
  2. Why is the namespace called __React and not simply React? That seems like a rather awkward "don't use me" name, yet IntelliJ IDEA has imported this all over my source code and it seems to work.
like image 275
Aaron Beall Avatar asked Feb 23 '16 23:02

Aaron Beall


People also ask

What is the difference between module and namespace in TypeScript?

Namespaces are a TypeScript-specific way to organize code. Namespaces are simply named JavaScript objects in the global namespace. This makes namespaces a very simple construct to use. Unlike modules, they can span multiple files, and can be concatenated using outFile .

What is declare namespace?

Adds a namespace declaration to a tag in the XML document represented by a SAX-writer object. Return type: LOGICAL.

What is the use of namespace in TypeScript?

The namespace is used for logical grouping of functionalities. A namespace can include interfaces, classes, functions and variables to support a single or a group of related functionalities. A namespace can be created using the namespace keyword followed by the namespace name.

What are ambient modules TypeScript?

Ambient modules is a TypeScript feature that allows importing libraries written in JavaScript and using them seamlessly and safely as if they were written in TypeScript. An ambient declaration file is a file that describes the module's type but doesn't contain its implementation.


1 Answers

This pattern is used to support UMD libraries.

These libraries generally put something into the global scope if they're loaded through a <script ...> tag, but return something to a module loader if invoked via a module system like RequireJS, CommonJS, or SystemJS.

In TypeScript, this means that if you import the module called 'react', you should get the same type as if you reference the global identifier React.

Most definition files simply write their .d.ts files such that the module shape and the global variable are always both present; the React authors didn't like that you could accidently refer to the global React if you were using a module loader (in which case the global wouldn't actually be there) so they separated out the declaration into __React, a separate .d.ts file that declared a global called React, and a module declaration for "react".

like image 148
Ryan Cavanaugh Avatar answered Oct 05 '22 05:10

Ryan Cavanaugh