o7planning

TypeScript Namespaces Tutorial with Examples

  1. What is namespace?
  2. Syntax
  3. Example
  4. Ambient Namespaces

1. What is namespace?

In JavaScript ES6, the module keyword is used to define a module, this allows you to define multiple modules in a file. TypeScript uses the namespace keyword with similar syntax and purposes.
See the following article to understand the concept of module and export/import keywords in TypeScript:
Note: Both "module" and "namespace" keywords can be used in TypeScript with similar syntax and usage. However, the TypeScript docs discourage the use of the "module" keyword in TypeScript code, it should only be used in JavaScript code.
In TypeScript, the "namespace" keyword is slightly more powerful than the "module" keyword. You can define a module across multiple files with the "namespace" keyword, and use the "--outFile" flag if you want them to be bundled together into a single file at compile time.
In this article we will use the term "namespace", you can also understand that it is similar to the concept of module in JavaScript. Basically "namespace" (as well as module) is a way to group variables, functions, classes,... with the same relationship into a logical group. It helps us to easily manage and maintain the application.

2. Syntax

By default, all code resources defined in a namespace have local scope. This means that the external environment does not know about them unless they are defined with the export keyword:
file1.ts
namespace Namespace_Name {
   export let sampleVariable: number = 100;
   export class SampleClass {
      // ...
   }
   export interface SampleInterface {
      // ...
   }
   export function sampleFunction() {
      // ...
   }
   // ...
}
In another file we can access the code resources exported in a namespace with the following syntax:
file2.ts
/// <reference path = "./file1.ts" />

Namespace_Name.sampleVariable;
Namespace_Name.sampleFunction();
Namespace_Name.SampleClass;
/// <reference path = "..." />
/// <reference path="..."/> is a necessary directive to tell the compiler where the namespace definition file is located.

3. Example

In this example, we define a namespace "MathLib" on three separate files, Math_file1.ts, Math_file2.ts and Math_file3.ts. Then use the "MathLib" namespace in the test.ts file. Finally, run the application in NodeJS and Web environment.
The Math_file1.ts file defines the "MathLib" namespace with a PI constant:
Math_file1.ts
namespace MathLib {
   export const PI:number = 3.14;
}
The Math_file2.ts file defines the "MathLib" namespace with the circleCircumference(radius) function to calculate the circumference of the circle. This function uses the PI constant defined in the Math_file1.ts file.
Math_file2.ts
/// <reference path="./Math_file1.ts" />

namespace MathLib {
    export function circleCircumference(radius:number):number {
        // Use the PI constant defined in Math_file1.ts
        return 2 * PI * radius;
    }
}
The Math_file3.ts file defines the "MathLib" namespace with the Circle class and the circleArea(radius) function. This file uses the constants and functions defined in the Math_file1.ts and Math_file2.ts files.
Math_file3.ts
/// <reference path="./Math_file1.ts" />
/// <reference path="./Math_file2.ts" />

namespace MathLib {  
    export function circleArea(radius: number): number {
        // Use the PI constant defined in Math_file1.ts
        return PI * radius * radius;
    }
    export class Circle {
        radius : number;
        constructor(radius: number) {
            this.radius = radius;
        }
        getArea()  {
            return circleArea(this.radius);
        }
        getCircumference() {
            // Use the function defined in Math_file2.ts
            return circleCircumference(this.radius);
        }
    }
 }
The test.ts file uses the "MathLib" namespace.
test.ts
/// <reference path="./Math_file3.ts" />

let circle = new MathLib.Circle(100);

let area = circle.getArea();
let circumference  = circle.getCircumference();

console.log('area = ' + area);
console.log('circumference = ' + circumference);
Compile all TypeScript files into JavaScript files:
tsc
Next, use the "--outFile" flag to compile the test.ts file and the libraries it uses into a single file:
tsc --outFile ./dist/all_in_one.js test.ts
After compiling, we get the JavaScript file, which should look like this:
test.js
"use strict";
/// <reference path="./Math_file3.ts" />
let circle = new MathLib.Circle(100);
let area = circle.getArea();
let circumference = circle.getCircumference();
console.log('area = ' + area);
console.log('circumference = ' + circumference);
all_in_one.js
var MathLib;
(function (MathLib) {
    MathLib.PI = 3.14;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file1.ts" />
var MathLib;
(function (MathLib) {
    function circleCircumference(radius) {
        // Use the PI constant defined in Math_file1.ts
        return 2 * MathLib.PI * radius;
    }
    MathLib.circleCircumference = circleCircumference;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file1.ts" />
/// <reference path="./Math_file2.ts" />
var MathLib;
(function (MathLib) {
    function circleArea(radius) {
        // Use the PI constant defined in Math_file1.ts
        return MathLib.PI * radius * radius;
    }
    MathLib.circleArea = circleArea;
    var Circle = /** @class */ (function () {
        function Circle(radius) {
            this.radius = radius;
        }
        Circle.prototype.getArea = function () {
            return circleArea(this.radius);
        };
        Circle.prototype.getCircumference = function () {
            // Use the function defined in Math_file2.ts
            return MathLib.circleCircumference(this.radius);
        };
        return Circle;
    }());
    MathLib.Circle = Circle;
})(MathLib || (MathLib = {}));
/// <reference path="./Math_file3.ts" />
var circle = new MathLib.Circle(100);
var area = circle.getArea();
var circumference = circle.getCircumference();
console.log('area = ' + area);
console.log('circumference = ' + circumference);
And run this example on NodeJS environment:
node ./dist/all_in_one.js
To run the example in the browser, we create the test.html file:
test.html
<html>
   <head>
      <script type="module" src="./dist/test.js"></script>
   </head>
   <body>
      <h3>To test, you need to run this file on an HTTP or HTTPS server.
         And see the results on the browser Console.
      </h3>
   </body>
</html>
This test.html file needs to be run on an HTTP or HTTPS server, and view the results in the browser's Console window.

4. Ambient Namespaces

  • TypeScript Ambients