Skip to main content

Modules & Namespaces

TypeScript modules and namespaces help you organize and structure your code. Let's learn how to use them effectively!

ES Modules

ES Modules are the standard way to organize code in modern TypeScript/JavaScript. They allow you to split your code into separate files and share code between them.

// math.ts
export const add = (a: number, b: number): number => a + b;
export const subtract = (a: number, b: number): number => a - b;

// You can also have a default export
export default class Calculator {
add(a: number, b: number): number {
return a + b;
}
}
// main.ts
import Calculator, { add, subtract } from './math';

const result = add(5, 3); // 8
const diff = subtract(10, 4); // 6

const calc = new Calculator();
const sum = calc.add(2, 3); // 5

Namespaces

While modules are the preferred way to organize code, TypeScript also supports namespaces (formerly known as "internal modules"). They're useful for bundling related functionality.

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

export class LettersOnlyValidator implements StringValidator {
isValid(s: string): boolean {
return /^[A-Za-z]+$/.test(s);
}
}
}

// Using the namespace
let validator = new Validation.LettersOnlyValidator();
let result = validator.isValid("Hello"); // true

Import/Export Types

TypeScript allows you to import and export types, interfaces, and other type-only declarations:

// types.ts
export interface User {
id: number;
name: string;
}

export type UserRole = 'admin' | 'user' | 'guest';

// Using type-only imports
import type { User, UserRole } from './types';

Module Resolution

TypeScript supports different module resolution strategies:

  • Classic: Legacy resolution strategy
  • Node: Follows Node.js module resolution rules
  • Modern: Uses ECMAScript module resolution rules

You can configure this in your tsconfig.json:

{
"compilerOptions": {
"moduleResolution": "node",
// or "classic", or "bundler"
}
}

Best Practices

  1. Prefer ES Modules over Namespaces

    • ES Modules are the standard
    • Better tooling support
    • Tree-shaking friendly
  2. Use Barrel Files

    // index.ts (barrel file)
    export * from './user';
    export * from './product';
    export * from './order';
  3. Explicit Imports

    // Good
    import { useState, useEffect } from 'react';

    // Avoid
    import * as React from 'react';
  4. Type-Only Imports

    • Use import type when importing only types
    • Helps with tree-shaking and build optimization

Remember that good module organization is key to maintaining a scalable TypeScript project. Choose your exports carefully and keep your modules focused and cohesive.