TypeScript - Modules

A module is designed with the idea to organize code written in TypeScript. Modules are broadly divided into −
Internal Modules
External Modules
Internal modules came in earlier version of Typescript. This was used to logically group classes, interfaces, functions into one unit and can be exported in another module. This logical grouping is named namespace in latest version of TypeScript. So internal modules are obsolete instead we can use namespace. Internal modules are still supported, but its recommended to use namespace over internal modules.
module TutorialPoint { 
   export function add(x, y) {  
      console.log(x+y); 
   } 
}

namespace TutorialPoint { 
   export function add(x, y) { console.log(x + y);} 
}

var TutorialPoint; 
(function (TutorialPoint) { 
   function add(x, y) { 
      console.log(x + y); 
   } 
   TutorialPoint.add = add; 
})(TutorialPoint || (TutorialPoint = {}));

External modules in TypeScript exists to specify and load dependencies between multiple external js files. If there is only one js file used, then external modules are not relevant. Traditionally dependency management between JavaScript files was done using browser script tags (<script></script>). But that’s not extendable, as its very linear while loading modules. That means instead of loading files one after other there is no asynchronous option to load modules. When you are programming js for the server for example NodeJs you don’t even have script tags.
There are two scenarios for loading dependents js files from a single main JavaScript file.
Client Side - RequireJs
Server Side - NodeJs
To support loading external JavaScript files, we need a module loader. This will be another js library. For browser the most common library used is RequieJS. This is an implementation of AMD (Asynchronous Module Definition) specification. Instead of loading files one after the other, AMD can load them all separately, even when they are dependent on each other.
When defining external module in TypeScript targeting CommonJS or AMD, each file is considered as a module. So it’s optional to use internal module with in external module.
If you are migrating TypeScript from AMD to CommonJs module systems, then there is no additional work needed. The only thing you need to change is just the compiler flag Unlike in JavaScript there is an overhead in migrating from CommonJs to AMD or vice versa.
The syntax for declaring an external module is using keyword ‘export’ and ‘import’.
//FileName : SomeInterface.ts 
export interface SomeInterface { 
   //code declarations 
}

To use the declared module in another file, an import keyword is used as given below. The file name is only specified no extension used.
import someInterfaceRef = require(“./SomeInterface”);

Let’s understand this using an example.
// IShape.ts 
export interface IShape { 
   draw(); 
}

// Circle.ts 
import shape = require("./IShape"); 
export class Circle implements shape.IShape { 
   public draw() { 
      console.log("Cirlce is drawn (external module)"); 
   } 
} 

// Triangle.ts 
import shape = require("./IShape"); 
export class Triangle implements shape.IShape { 
   public draw() { 
      console.log("Triangle is drawn (external module)"); 
   } 
}
   
// TestShape.ts 
import shape = require("./IShape"); 
import circle = require("./Circle"); 
import triangle = require("./Triangle");  

function drawAllShapes(shapeToDraw: shape.IShape) {
   shapeToDraw.draw(); 
} 

drawAllShapes(new circle.Circle()); 
drawAllShapes(new triangle.Triangle()); 

The command to compile the main TypeScript file for AMD systems is −
tsc --module amd TestShape.ts

On compiling, it will generate following JavaScript code for AMD.
//Generated by typescript 1.8.10
define(["require", "exports"], function (require, exports) {
});

//Generated by typescript 1.8.10
define(["require", "exports"], function (require, exports) {
   var Circle = (function () {
      function Circle() {
      }
      Circle.prototype.draw = function () {
         console.log("Cirlce is drawn (external module)");
      };
      return Circle;
   })();
   exports.Circle = Circle;
});

//Generated by typescript 1.8.10
define(["require", "exports"], function (require, exports) {
   var Triangle = (function () {
      function Triangle() {
      }
      Triangle.prototype.draw = function () {
         console.log("Triangle is drawn (external module)");
      };
      return Triangle;
   })();
   exports.Triangle = Triangle;
});

//Generated by typescript 1.8.10
define(["require", "exports", "./Circle", "./Triangle"], 
   function (require, exports, circle, triangle) {
   
   function drawAllShapes(shapeToDraw) {
      shapeToDraw.draw();
   }
   drawAllShapes(new circle.Circle());
   drawAllShapes(new triangle.Triangle());
});

The command to compile the main TypeScript file for Commonjs systems is
tsc --module commonjs TestShape.ts

On compiling, it will generate following JavaScript code for Commonjs.
//Generated by typescript 1.8.10
var Circle = (function () {
   function Circle() {
   }
   Circle.prototype.draw = function () {
      console.log("Cirlce is drawn");
   };
   return Circle;
})();

exports.Circle = Circle;

//Generated by typescript 1.8.10
var Triangle = (function () {
   function Triangle() {
   }
   Triangle.prototype.draw = function () {
      console.log("Triangle is drawn (external module)");
   };
   return Triangle;
})();
exports.Triangle = Triangle;

//Generated by typescript 1.8.10
var circle = require("./Circle");
var triangle = require("./Triangle");

function drawAllShapes(shapeToDraw) {
   shapeToDraw.draw();
}
drawAllShapes(new circle.Circle());
drawAllShapes(new triangle.Triangle());

Cirlce is drawn (external module)
Triangle is drawn (external module)