Modules and Namespaces in TypeScript

Learn how to use Modules and Namespaces in TypeScript with this detailed tutorial. Includes basic and advanced examples to help you master Modules and Namespaces.

Introduction

Modules and namespaces in TypeScript are powerful tools for organizing code. Modules provide a way to split your code into reusable pieces, while namespaces provide a way to organize your code into logical groups.

Modules

Modules in TypeScript provide a way to split your code into reusable pieces. Here are some basic and advanced examples of using modules:

Basic Example

You can define and export a module, then import it in another file.

// math.ts
export function add(x: number, y: number): number {
    return x + y;
}

// app.ts
import { add } from './math';

console.log(add(2, 3)); // 5

Default Exports

You can export a single default export from a module.

// person.ts
export default class Person {
    constructor(public name: string, public age: number) {}
}

// app.ts
import Person from './person';

let john = new Person('John Doe', 30);
console.log(john.name); // John Doe

Re-exporting

You can re-export members from another module.

// shapes.ts
export { Circle } from './circle';
export { Square } from './square';

// app.ts
import { Circle, Square } from './shapes';

let circle = new Circle();
let square = new Square();

Namespaces

Namespaces in TypeScript provide a way to organize your code into logical groups. Here are some basic and advanced examples of using namespaces:

Basic Example

You can define a namespace to group related code.

namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }

    const lettersRegexp = /^[A-Za-z]+$/;
    const numberRegexp = /^[0-9]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }

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

let strings = ['Hello', '98052', '101'];
let validators: { [s: string]: Validation.StringValidator } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();

for (let s of strings) {
    for (let name in validators) {
        let isMatch = validators[name].isAcceptable(s);
        console.log(`'${s}' ${isMatch ? 'matches' : 'does not match'} '${name}'.`);
    }
}

Splitting Namespaces Across Files

You can split a namespace across multiple files.

// validation.ts
namespace Validation {
    export interface StringValidator {
        isAcceptable(s: string): boolean;
    }
}

// lettersOnlyValidator.ts
/// 
namespace Validation {
    const lettersRegexp = /^[A-Za-z]+$/;

    export class LettersOnlyValidator implements StringValidator {
        isAcceptable(s: string) {
            return lettersRegexp.test(s);
        }
    }
}

// zipCodeValidator.ts
/// 
namespace Validation {
    const numberRegexp = /^[0-9]+$/;

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

// app.ts
/// 
/// 
/// 
let strings = ['Hello', '98052', '101'];
let validators: { [s: string]: Validation.StringValidator } = {};
validators['ZIP code'] = new Validation.ZipCodeValidator();
validators['Letters only'] = new Validation.LettersOnlyValidator();

for (let s of strings) {
    for (let name in validators) {
        let isMatch = validators[name].isAcceptable(s);
        console.log(`'${s}' ${isMatch ? 'matches' : 'does not match'} '${name}'.`);
    }
}

Alias for Namespaces

You can use aliases to shorten namespace references.

namespace Shapes {
    export namespace Polygons {
        export class Triangle {}
        export class Square {}
    }
}

import polygons = Shapes.Polygons;
let sq = new polygons.Square();

Conclusion

Modules and namespaces in TypeScript provide powerful ways to organize and manage your code. By using modules, you can split your code into reusable pieces, and by using namespaces, you can group related code together. Mastering these features will help you write more maintainable and scalable code.