TypeScript

TypeScript Modules

In this tutorial, you will learn about the TypeScript modules and how to use the to structure your code.

Introduction to TypeScript modules

Since ES6, JavaScript started supporting modules as the native part of the language. TypeScript shares the same module concept with JavaScript.

A TypeScript module can contain both declarations and code. A module executes within its own scope, not in the global scope. It means that when you declare variables, functions, classes, interfaces, etc., in a module, they are not visible outside the module unless you explicitly export them using export statement.

On the other hand, if you want to access variables, functions, classes, etc., from a module, you need to import them using the import statement.

Like ES6, when TypeScript file contains a top-level import or export, it is treated as a module.

Creating a new module

The following creates a new module called Validator.ts and declares an interface named Validator:

export interface Validator {
    isValid(s: string): boolean
}

In this module, we place the export keyword before the interface keyword to expose it to other modules.

In other words, if you do not use the export keyword, the Validator interface is private in the Validator.ts module, therefore, it cannot be used by other modules.

Export statements

Another way to export a declaration from a module is to use the export statement. For example:

interface Validator {
    isValid(s: string): boolean
}

export { Validator };

TypeScript also allows you to rename declarations for module consumers, like this:

interface Validator {
    isValid(s: string): boolean
}

export { Validator as StringValidator };

In this example other modules will use the Validator interface as the StringValidator interface.

Importing a new module

To consume a module, you use the import statement. The following creates a new module EmailValidator.ts that uses the Validator.ts module:

import { Validator } from './Validator';

class EmailValidator implements Validator {
    isValid(s: string): boolean {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(s);
    }
}

export { EmailValidator };

When you import a module, you can rename it like this:

import { Validator as StringValidator } from './Validator';

Inside the EmailValidator module, you use the Validator interface as the StringValidator interface instead:

import { Validator as StringValidator } from './Validator';

class EmailValidator implements StringValidator {
    isValid(s: string): boolean {
        const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
        return emailRegex.test(s);
    }
}

export { EmailValidator };

The following illustrates how to use the EmailValidator module in the App.ts file:

import { EmailValidator } from './EmailValidator';

let email = 'john.doe@typescripttutorial.net';
let validator = new EmailValidator();
let result = validator.isValid(email);

console.log(result);

Output:

true

Importing types

The following declares a type called in Types.ts module:

export type alphanumeric = string | number;

To import the alphanumeric type from the Types.ts module, you can use the import type statement:

import type {alphanumeric} from './Types';

Note that TypeScript has supported the import type statement since version 3.8. Prior to TypeScript 3.8, you need to use the import statement instead:

import {alphanumeric} from './Types';

Importing everything from a module

To import everything from a module, you use the following syntax:

import * from 'module_name';

Re-exports

The following creates a new module called ZipCodeValidator.ts that uses the Validator.ts module:

import { Validator } from './Validator';

class ZipCodeValidator implements Validator {
    isValid(s: string): boolean {
        const numberRegexp = /^[0-9]+$/;
        return s.length === 5 && numberRegexp.test(s);
    }
}

export { ZipCodeValidator };

You can wrap the EmailValidator and ZipCodeValidator modules in a new module by combining all their exports using the following syntax:

export * from 'module_name';

The following example illustrates how to wrap the the EmailValidator.ts and ZipCodeValidator.ts modules in the FormValidator.ts module:

export * from "./EmailValidator";
export * from "./ZipCodeValidator";

Default Exports

TypeScript allows each module to have one default export. To mark an export as a default export, you use the default keyword.

The following shows how to export the ZipCodeValidator as a default export:

import { Validator } from './Validator';

export default class ZipCodeValidator implements Validator {
    isValid(s: string): boolean {
        const numberRegexp = /^[0-9]+$/;
        return s.length === 5 && numberRegexp.test(s);
    }
}

To import a default export, you use a different import syntax like this:

import default_export from 'module_name';

The following shows how to use the default export from the ZipCodeValidator in the App.ts file:

import ZipCodeValidator from './ZipCodeValidator';

let validator = new ZipCodeValidator();
let result = validator.isValid('95134');

console.log(result);

Output:

true

Conclusion

  1. TypeScript shares the same module concept with ES6 module. A module can contain both declarations and code.
  2. In a module, variables, functions, classes, interfaces, etc., executes on its own scope, not the global scope.
  3. Use export statement to export variables, functions, classes, interfaces, type, etc., from a module.
  4. Use import statement to access exports from other modules.

About the Author: Narayan selvan

I am a front-end developer.