Open In App

How to declare a module in TypeScript ?

Last Updated : 04 Oct, 2021
Improve
Improve
Like Article
Like
Save
Share
Report

A module is a piece of code that can be called or used in another code. There is nothing new about modules in Typescript. The concept of the module was introduced by JavaScript with ECMAScript 2015 release. Typescript is just re-using this feature.

Will the code not work without Modules?

Of course, it will. The code will still work. But there are major drawbacks with the code that is not modularized.

Let’s say we created a very basic chatting application that can either send or receive text messages. Initially, we have added our entire code in just 2-3 files and the application is working great. Later we decided to add a feature to record and send audio messages also. For this, we again added more code into the same files and the application is still doing great. Later we decided to add features like share images or share videos or maybe some large documents as well and we kept on dumping code into the same files or maybe 1 or 2 extra files. Now there is a problem. Here are few issues that we can foresee:

  1. Our app will start becoming slow (or super slow at one point).
  2. Frequent crashing of the application causing potential loss of data
  3. Code base will become spaghetti (impossible to maintain)
  4. Bug fixing or debugging is another big issue
  5. Nightmare for the testing team

All the above problems (and more) can be solved if we just make our code more modular.

Development efforts without using module: Let’s mimic a scenario. We want to buy some fruits. Maybe Apple, Kiwi, and Strawberry. We’ll create 3 separate classes for all 3. Since all 3 are fruits so they share some common features like name, color, and quantity. So we’ll create one more class (as a data type) with one method. Let’s create classes one by one.

1. Creating Apple class: Right-click into project folder and click ‘New file’. Call it apple.ts. First we will define Fruit class here to be used as data type for apple and In the same file We will define class for Apple also:

Javascript




class Fruit {
 
  // Properties that every fruits have
  name: string;
  color: string;
  quantity: number;
 
  // To initialize the values
  constructor(name, color, quantity) {
      // Initialize values using this operator
  }
 
  myCart() {
     // A simple placeholder text
      console.log("I have " + this.quantity +
      " " + this.color + " " + this.name +
      " in my cart");
  }
}
 
class Apple {
  // Initialize Fruits class with values
  fruits: Fruits = new Fruits(..., ..., ...);
 
  constructor() {
  // call method to see everything is correct
      this.fruits.myCart();
  }
}
 
// initialize apple class and call
// its constructor automatically
var obj: Apple = new Apple();


 
We will do the same procedure for Kiwi class

2. Creating Kiwi class: Right-click into project folder and click ‘New file’. Call it kiwi.ts. First we will define Fruit class here to be used as data type for kiwi and In the same file we will define class for Kiwi also:

Javascript




class Fruit {
 
  // Properties that every fruits have
  name: string;
  color: string;
  quantity: number;
 
  // Initialize the values
  constructor(name, color, quantity) {
 
      // Initialize values using this operator
  }
 
  myCart() {
 
     // A simple placeholder text
      console.log("I have " + this.quantity +
      " " + this.color + " " + this.name +
      " in my cart");
  }
}
 
class Kiwi {
 
  // Initialize Fruits class with values
  fruits: Fruits = new Fruits(..., ..., ...);
 
  constructor() {
 
  // Call method to see everything is correct
      this.fruits.myCart();
  }
}
 
// Initialize kiwi class and
// call its constructor automatically
var obj: Kiwi = new Kiwi();


 
3. Creating Strawberry class: Right-click into the project folder and click ‘New file’. Call it strawberry.ts. First we will define Fruit class here to be used as the data type for strawberry and In the same file we will define class for Strawberry also:

Javascript




class Fruit {
 
  // Properties that every fruits have
  name: string;
  color: string;
  quantity: number;
 
  // Initialize the values
  constructor(name, color, quantity) {
 
      // Initialize values  using this operator
  }
 
  myCart() {
 
     // A simple placeholder text
      console.log("I have " + this.quantity +
      " " + this.color + " " + this.name +
      " in my cart");
  }
}
 
class Strawberry {
 
  // Initialize Fruits class with values
  fruits: Fruits = new Fruits(..., ..., ...);
   
  constructor() {
   
      // Call method to see everything is correct
      this.fruits.myCart();
  }
}
 
// Initialize strawberry class and
// call its constructor automatically
var obj: Strawberry = new Strawberry();


 
Reduced development efforts using modular approach: There is a major flaw in the above approach. Yes, you are right. Redefining the same Fruits class, again and again, is painfully stupid. That’s where the module comes into the picture. What if we keep Fruits class in one file and call it one module and then just call that class/module wherever required. This will save a considerable amount of time and effort of developer. Let’s do that quickly.

Step 1: Create a new file called Fruits.ts

Step 2: Remove Fruits class definition from all 3 classes

Step 3: Paste it at only one location i.e. file Fruits.ts

Javascript




export class Fruit {
 
  // Properties that every fruits have
  name: string;
  color: string;
  quantity: number;
 
  // Initialize the values
  constructor(name, color, quantity) {
 
      // Initialize values using this operator
  }
 
  myCart() {
 
     // A simple placeholder text
      console.log("I have " + this.quantity +
      " " + this.color + " " + this.name +
      " in my cart");
  }
}
 
console.log("Hello world!");


 
Notice that we are using the export keyword in the first place. Export keyword actually makes it possible for our class (or interface) to be used somewhere else in the project. In parallel, we use Import statement in the module that wants to use the exported module.

Also notice that we have added one console log statement at the end of the file. It’s not required, but we want to tell you an important fact later in this article itself. For now, you can just ignore it and assume it is not there.

Now when we have our module ready. We can just call it in our classes. Technically we call it ‘importing‘ and we use a keyword called ‘import‘.

Syntax:

import {classname} from './location';

Let’s import the same quickly:

Filename: Apple.ts

Javascript




import { Fruits } from './main';
 
class Apple {
  fruits: Fruits = new Fruits('apples', 'green', 5);
  constructor() {
      this.fruits.myCart();
  }
}
var obj: Apple = new Apple();


 
Filename: Kiwi.ts

Javascript




import { Fruits } from './main';
class Kiwi {
  fruits: Fruits = new Fruits('kiwi', 'golden', 2);
  constructor() {
      this.fruits.myCart();
  }
}
var obj: Kiwi = new Kiwi();


 
Filename: Strawberry.ts

Javascript




import { Fruits } from './main';
class Strawberry {
  fruits: Fruits = new Fruits('strawberries', 'red', 5);
  constructor() {
      this.fruits.myCart();
  }
}
var obj: Strawberry = new Strawberry();


 
See how clean it looks. It’s easy to understand and easy to maintain now. That’s the whole idea behind the modular approach.

Some Left over points: We have added one console statement at the last. There is the reason for that. Let me first show you the output. 

Output

See every time we run the files, we are getting a class-specific output but also we are getting “Hello world!”

The reason is that it doesn’t belong to the exported class. Then why it was called. The reason is whenever we import a module, the entire module is once executed as one simple program and every line inside the file will get executed no matter it is inside the export class braces or not. So be careful what you put in there. In an expert’s opinion, there should be no stray line of code. Use them in some method or just remove those statements if they are not required.

Summary: So, the module is nothing but a concept or approach where a piece of code is kept separated and exported explicitly so that other pieces of code can import it. We use export keywords to make a class available publicly and we use import to use that exported module.

How to execute the code:

First we will run:

tsc apple.ts

Then we will run:

node apple.js

This is so because not all browsers understand Typescript like they understand JavaScript. So the Typescript first has to be compiled into JavaScript that’s why we use node command for that. We can also club the two commands together using the AND operator:

For Linux:

tsc apple.ts && node apple.js

For windows I can use pipe operator:

tsc apple.ts | node apple.js

Similarly, I can run Kiwi and Strawberry classes.

Final output:

One last note:

This is the professional way to write the code and is globally followed. So, tomorrow if you are writing the code or reviewing someone else’s code please pay special attention to the code modularity. This will make your life easier.

 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads