Table of contents
1.
Introduction
2.
Namespace Syntax
2.1.
Declaring Namespace
2.2.
Accessing Namespace Class
3.
Namespace Example
4.
Nested Namespaces
5.
Validators
6.
Namespaced Validators
7.
FAQs
8.
Key Takeaways
Last Updated: Mar 27, 2024

NameSpaces in TypeScript

Author Parth Jain
0 upvote
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

While sorting and storing household items in our daily lives, we keep all the medical supplies in a first aid box. Similarly, all the tools and equipment are stored in a toolbox, and all the fruits and vegetables are stored in the refrigerator. This logical grouping of items is done to access them effortlessly in time of need.
The same principle applies in coding with the help of Namespace. A Namespace is a logical way of grouping related code to make the code appear less complex and readable.
In a sizeable unordered project, the variables are likely to be overwritten or reinitialized due to the usage of multiple javascript files. They can lead to a global namespace pollution problem.

Namespace Syntax

Now that we have a slight idea about Namespaces, it is time to understand the syntax for creating a namespace.
A namespace can be created using the namespace keyword followed by the Namespace's name. Then, all the functions, interfaces, classes, and variables can be enclosed inside the body of the Namespace using the curly brackets { }.

Declaring Namespace

namespace exampleNamespace { 
   export interface sampleInterface {      }  
   export class sampleClass {      }  
}

Accessing Namespace Class

To access a namespace class, the namespace name followed by the dot operator (.) and the name of the class is written.

exampleNamespace.sampleClass;

Namespace Example

//NAMESPACE
namespace Math {  
  function addition(a, b) {  
    console.log(a+b); 
 } 
  function subtraction(a, b) {  
   console.log(a-b); }
 } 
Math.addition(5,4);
Math.subtraction(9,7);

Math is Namespace's name in the above example that holds two functions, addition and subtraction.
To call the two functions, the dot operator is used.

Nested Namespaces

A namespace can hold another namespace inside it. To access the members of the nested namespace, the dot operator (.) can be used.

// NESTED NAMESPACE
namespace Algebra{ 
namespace Math { 
   function addition(a, b) {  
     console.log(a+b); 
  } 
   function subtraction(a, b) {  
    console.log(a-b); }
  }
} 
Algebra.Math.addition(5,4);
Algebra.Math.subtraction(9,7);

In the above example, Algebra is a namespace that holds the namespace Math, which contains two functions, addition and subtraction.

Validators

TypeScript is famous for its type checking and simplicity. Due to type checking, the number of coding errors is reduced significantly. However, even TypeScript is not immune to undefined errors such as undefined is not a function and can not read undefined property.
To comprehend the above statement let us look at an example.

// Typescript definition
type Example = {
  name: string,
  age?: number,
  animal: {
    name: string,
    legs: number,
  }[],
};
// external API
const fetchData = (): Promise<Example> => {};
const getBiped = async () => {
  const data = await fetchData();
  console.log(data);
  // { name: 'Anny' }
  return data.animal.find(animal => animal.legs === 2); };

The above code fails upon execution as the external API does not contain animal inside it. Hence, when data.animal.find is called the error Uncaught ReferenceError: Cannot read property 'find' of undefined.
We must validate the code to avoid such errors, leading to uneventful failures. This is where Validators come to play. Validators are checks performed on the code to avoid halting the code cycle due to errors. 
To further understand the working of validators, check the code below.

interface StringValidator {
 isOkay(s: string): boolean;
}
let lettersRegexp = /^[A-Za-z]+$/;
let numberRegexp = /^[0-9]+$/;

class LettersOnlyValidator implements StringValidator {
 isOkay(s: string) {
   return lettersRegexp.test(s);
 }
}
class ZipCodeValidator implements StringValidator {
 isOkay(s: string) {
   return s.length === 5 && numberRegexp.test(s);
 }
}

let strings = ["Peter", "80422", "951"];
// Validators 
let validators: { [s: string]: StringValidator } = {};
validators["ZIP code"] = new ZipCodeValidator();
validators["Letters only"] = new LettersOnlyValidator();
// Check if each string passed each validator
for (let s of strings) {
 for (let name in validators) {
   let isMatch = validators[name].isOkay(s);
   console.log(`'${s}' ${isMatch ? "matches" : "does not match"} '${name}'.`);
 }
}

Namespaced Validators

Validators are crucial when it comes to creating an error-free code. However, If a code requires multiple validators, it can become challenging to keep track of all the validators. Thus, it can make the code complex and error-prone. When a separate namespace is created to enclose all the validators, it is known as a Namespaced Validator.
Now, as all the validators are enclosed inside a namespace typically named validation, the validation logic is located and managed efficiently. 

namespace Validation {
 export interface StringValidator {
   isOkay(s: string): boolean;
 }
 const lettersRegexp = /^[A-Za-z]+$/;
 const numberRegexp = /^[0-9]+$/;
 export class LettersOnlyValidator implements StringValidator {
   isOkay(s: string) {
     return lettersRegexp.test(s);
   }
 }
 export class ZipCodeValidator implements StringValidator {
   isOkay(s: string) {
     return s.length === 5 && numberRegexp.test(s);
   }
 }
}
// Some samples to try
let strings = ["Hello", "98052", "101"];
// Validators to use
let validators: { [s: string]: Validation.StringValidator } = {};
validators["ZIP code"] = new Validation.ZipCodeValidator();
validators["Letters only"] = new Validation.LettersOnlyValidator();
// Show whether each string passed each validator
for (let s of strings) {
 for (let name in validators) {
   console.log(
     `"${s}" - ${
       validators[name].isOkay(s) ? "matches" : "does not match"
     } ${name}`
   );
 }
}

FAQs

  1. Is Namespace deprecated TypeScript?
    Currently, the Typescript Modules are used more in comparison to Namespaces. However, this does not mean that Namespaces are deprecated. 
     
  2. What is the difference between module and Namespace in TypeScript?
    Typescript Modules are a way of organizing code in different files, whereas Typescript Namespaces are a way of organizing in the same file to make it appear less complex.

Key Takeaways

In this article, we learned about Typescript Namespaces and how they make coding in the same file efficient and effortless. We also learned about the implementation of nested namespaces and validators. However, this isn't enough, as there is always much more to explore and learn about this vast field of Web Development. To know more about TypeScript and its intricacies, check out the articles on TypeScript or enroll in our highly curated Web Development course.   

 

Live masterclass