The declare
keyword is used to create ambient declarations in typescript, providing the compiler with type informations about each module.
Before ES6, JavaScript has no concept of module
. Every variable you create will end up on the global scope.
eg. If you have the following 2 files:
// a.js
var name = 'a';
// b.js
var name = 'b';
name
will be a global variable, so if b.js is loaded after a.js, name
will have the value of 'b'
;
The module pattern was introduced to prevent these variable clashes:
// a.js
(function() {
var name = 'a';
})();
// b.js
(function() {
var name = 'b';
})();
Now each file will have its own name
variable within the function scope. They cannot be accessed outside the function.
When you want to export the variables, you can do so by passing in a global variable:
var module = {}; // this is global
// a.js
(function(mod) {
var name = 'a';
mod.a = name;
})(module); // <-- passing the module variable into the function scope of a.js
// b.js
(function(mod) {
var name = 'b';
mod.b = name;
})(module);
Now the values have been exported to module.a
and module.b
. Before ES6 this is the mechanism used by many JS libraries to create modules.
Typescript called this mechanism internal modules
which has subsequently been renamed to namespaces
.
Namespaces are simply named JavaScript objects in the global namespace
The ambient type declaration of these global module variables can be defined using the declare namespace
syntax.
Since the introduction of ES6, module has become a feature of the language itself, and can be created using the import & export syntax. The type declarations of these modules will therefore use the declare module
syntax.
Starting with ECMAScript 2015, modules are native part of the language, and should be supported by all compliant engine implementations. Thus, for new projects modules would be the recommended code organization mechanism
https://www.typescriptlang.org/docs/handbook/namespaces-and-modules.html
As for your second question, it is generally a better design to reduce the level of nesting for your module objects when possible.