I. namespace - namespace
If you are familiar with C++, Java, C#, etc., namespace should not be new to you. namespace can be used to encapsulate a piece of code, and code outside namespace cannot directly access the code inside namespace.
Namespaces are defined by the
namespace keyword. The format is as follows.
In the following example,
Lib are not accessible outside the
If you use
tsc to compile the above code, the compiler will report an error directly.
The contents of the compiled js file are as follows.
As you can see, the namespace principle is implemented through Immediately Execute Function (IIFE), where the function is executed and the variables inside the function are not available from the outside world (global scope).
In order to get the variables or functions inside namespace, you can expose the variables in namespace through the
export keyword and then access the exposed variables through namespace names .
tsc, the compilation passed and the compiled js file reads as follows.
You can see that the compiled code, by assigning the
getName function to
Lib.getName, implements the
export function, so you can access the variables inside the namespace from outside the namespace.
As you can see from the compiled js code, namespace is essentially an object, and we can access the variables inside the namespace through the properties of the object .
II. Exporting types and namespaces
As with modules, you can export type information from namespaces and access the exported types by the namespace name.
The compiled js code is as follows. The compiled js file does not contain any type information.
Namespaces can be nested and child namespaces can be exported by the parent namespace and then access the variables of the internal namespace through the namespace name chain.
The compiled js file is as follows.
Because namespaces can be nested, when the embedding level is very deep, it is troublesome to access through namespace name chain, for example
Space1.Space2.Space3.Space4.xxx, you can simplify the namespace name chain by aliasing.
The above code simplifies access to
MyLibA.Functions by adding an alias to
var API_FUNCTIONS = MyLibA.Functions;.
But using the same approach, adding an alias to
MyLibA.Types will report an error because the
MyLibA.Types namespace only contains type information internally, no other fields exist, so it is essentially non-existent (the compiled JS code will remove the type information). You can use
type Person = MyLibA.Types.Person to simplify access.
TypeScirpt also supports using the
import <alias> = statement to simplify access to internal namespaces, and adding aliases to
MyLib.Types does not report an error, which is a syntactic sugar given to us by typescript to create aliases for namespaces.
IV. Importing Namespaces
Since a namespace is essentially an Object, you can import namespaces with the import statement.
To import namespaces, you need the execution environment of the code to support namespaces, the above example is ES Modules, if it is a NodeJS environment, which supports the CommonJS module system, then you need to use
exports statements to import and export.
//, which works only during the ts compilation phase and is used to instruct the ts compiler to locate ts files.
/// <reference path="" /> is similar to
#include in the c language. It must appear at the top of the file and is essentially a comment, so it is only useful at the compile stage.
The value of the
path attribute specified by
reference is the path to another ts file, which is used to tell the compiler what dependencies the current file compiles with, somewhat similar to the
import statement, but without the need to import the specified variables.
reference specifies a file, typescript will automatically include this file in the compilation process when compiling, and all global variables within this file will be available in the current file (the file specified by
reference to exist).
As an example, in
index.ts, all global variables are obtained in the current file (the file specified by
/// <reference path=". /math.ts" /> introduces the
tsc index.ts, after compilation there are two files
math.js with the following contents.
Of course we can’t execute this code in the Node environment because it’s two separate files and there’s no require statement. We need to first package them into a single file
bundle.js and then execute it with the command
In the browser environment, we need to load the
index.js files sequentially using the
A better approach is to use the
-outFile configuration option of
tsc to package the output file into a bundle, and ts will automatically compile the file according to the
tsc --outFile bundle.js index.ts command to compile the file, and the compiled bundle.js file will have the following contents.
VI. Extending namespaces
You can extend an already defined namespace using the
reference directive. Look directly at the following example.
c.ts is introduced via the
reference directive, which extends
MyLibA, adds the
defaultPerson variable, and all variables in
MyLibA are accessible in the
b.ts file, e.g.
getPerson( 'John Doe', 21 );
a.ts file, the
b.ts is introduced with the
reference directive, and the
defaultPerson members inside the namespace
MyLibA are accessible in the
This is the end of this chapter. namespaces are powerful, but if you ask me, when should I use namespaces? I would say, try to avoid namespaces and use the Modules system instead, now that Es Module is convenient, you can also use CommonJS instead of namespaces in node environments.
Namespaces came before ES Module, so maybe one day namespaces will be deprecated.