TypeScript

14. Mastering Modules in TypeScript: A Comprehensive Guide

Modules are essential for organizing, reusing, and maintaining code in TypeScript. They help encapsulate functionality, avoid global scope pollution, and enable efficient dependency management. Let’s explore named exportsdefault exports, and other key concepts with practical examples.


Why Use Modules?

  • Encapsulation: Keep variables/functions private unless explicitly exported.

  • Reusability: Share code across files.

  • Structure: Break down complex apps into manageable pieces.

  • Dependency Management: Explicitly declare dependencies.


Key Concepts

TypeScript supports two module systems:

  1. ES Modules (Modern: import/export)

  2. CommonJS (Node.js: require/module.exports).

This guide focuses on ES Modules.


1. Named Exports (Multiple Exports per File)

Export individual values (variables, functions, classes) by name.
Syntaxexport { name1, name2, ... }

Example:

typescript
// 📁 utils.ts
export const PI = 3.14; // Named export (variable)

export function sum(a: number, b: number): number { // Named export (function)
  return a + b;
}

class Calculator { // Named export (class)
  static multiply(a: number, b: number): number {
    return a * b;
  }
}

export { Calculator }; // Export declared class

Import Named Exports:

typescript
// 📁 app.ts
import { PI, sum, Calculator } from './utils';

console.log(PI); // 3.14
console.log(sum(2, 3)); // 5
console.log(Calculator.multiply(4, 5)); // 20

2. Default Export (Single Export per File)

Export one primary value (e.g., a function, class, or object).
Syntaxexport default value;

Example:

typescript
// 📁 Logger.ts
export default class Logger { // Default export (class)
  static log(message: string): void {
    console.log(`[LOG] ${message}`);
  }
}

// ❌ Avoid multiple default exports in one file!

Import Default Exports:

typescript
// 📁 app.ts
import Logger from './Logger'; // No braces needed!

Logger.log("Hello Modules!"); // [LOG] Hello Modules!

3. Combining Named and Default Exports

Mix both in one module:

typescript
// 📁 math.ts
export const PI = 3.14; // Named export

export default function add(a: number, b: number): number { // Default export
  return a + b;
}

Import Both:

typescript
// 📁 app.ts
import add, { PI } from './math'; // Default + named

console.log(add(PI, 10)); // 13.14

4. Renaming Exports/Imports

Avoid naming collisions with aliases:

typescript
// 📁 app.ts
import { sum as addNumbers } from './utils'; // Rename named export
import Logger as MyLogger from './Logger'; // Rename default export

MyLogger.log(addNumbers(1, 2)); // [LOG] 3

5. Re-exporting (Barrel Files)

Aggregate exports from multiple files:

typescript
// 📁 math/index.ts
export { default as add } from './add'; // Re-export default
export { PI } from './constants'; // Re-export named

Usage:

typescript
// 📁 app.ts
import { add, PI } from './math'; // Clean import path

6. Import Everything as a Namespace

Bundle all exports into a single namespace object:

typescript
// 📁 app.ts
import * as Utils from './utils';

console.log(Utils.PI); // 3.14
console.log(Utils.sum(1, 2)); // 3

Best Practices

  1. Prefer Named Exports:

    • Ensures consistent naming across imports.

    • Facilitates tree-shaking (dead code elimination).

  2. Use Default Exports Sparingly:

    • Ideal for primary classes/functions (e.g., React.Component).

  3. Barrel Files:

    • Simplify imports in large projects (e.g., import { User, Post } from './models').


Common Pitfalls

  • Default vs. Named Confusion:

    typescript
    // ❌ Error: Named import for default export
    import { Logger } from './Logger'; // Incorrect! 
    
    // ✅ Correct
    import Logger from './Logger';
  • Circular Dependencies:
    Avoid modules importing each other (e.g., A → B → A).


Conclusion

Modules are the backbone of scalable TypeScript applications:

  • Named Exports: For multiple values.

  • Default Exports: For a module’s primary functionality.

  • Re-exports: Simplify dependency graphs.

By mastering these patterns, you’ll write cleaner, more maintainable code. 🚀

Pro Tip: Configure tsconfig.json with "module": "ES2015" (or higher) for modern projects!

Leave a Reply

Your email address will not be published. Required fields are marked *