TypeScript Module Import and Export Best Practices

Module Import/Export Mechanism

The TypeScript module system organizes code through the import and export keywords. Its core mechanisms include:

  1. Module Definition and Export
    Modules are defined via .ts or .dts files, using the export keyword to export interfaces, functions, or classes. For example:

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

    Exported modules can be referenced by other files through import statements.

  2. Default and Named Exports
    Default exports (default) allow a single module to provide a default interface, while named exports (using as) can assign aliases to exported content:

    // geometry.ts
    export default class Circle { ... }
    export class Square { ... as Shape }
    
  3. Module Scope
    Code within modules possesses an enclosed scope, preventing naming conflicts. For example:

    // utils.ts
    export function formatText(text: string): string {
      return text.toUpperCase();
    }
    

    The formatText function cannot be accessed directly from outside; it must be introduced via import.

Best Practices for Import/Export

  1. Module Separation and Dependency Management
    Split functional modules into independent module files, explicitly defining dependencies through import. For example:

    // user.ts
    import { getUsername } from './userUtils';
    export function displayUser(user: User) {
      console.log(getUsername(user));
    }
    

    Use import * as to batch import multiple modules:

    import { getUser, getProfile } from './user';
    
  2. Avoid Naming Conflicts
    Name exported content with unique identifiers to avoid conflicts with global variables. For example:

    export const PI = 3.14159 as const;
    

    Avoid using window or global objects as module exports.

  3. Module Bundling and Performance Optimization
    Use module bundlers (such as Webpack, Rollup) to optimize the build process and avoid redundant bundling. For example:

    // webpack.config.js
    module.exports = {
      resolve: {
        alias: {
          '@': path.resolve(__dirname, './src')
        }
      }
    };
    

    Improve performance by using import { foo } from 'module' instead of require.

  4. Module Version Control
    Install type definition files using @types to ensure module compatibility. For example:

    npm install @types/react
    

    Specify the module type via the type field to avoid type errors.

Common Issues and Solutions

  1. Unexported Modules Cannot Be Used
    Ensure modules export required content through export, or provide a default interface using default exports (default).

  2. Scope Pollution
    Restrict access scope for functions or variables within modules to prevent accidental usage by external code. For example:

    // utils.ts
    export function calculate() { ... }
    

    Use the private modifier to limit access permissions.

  3. Module Resolution Path Issues
    Configure moduleResolution in tsconfig.json as node to ensure correct module resolution paths. For example:

    {
      "moduleResolution": "node",
      "types": ["node"]
    }
    
  4. Module Bundler Configuration
    Configure bundlers according to project requirements, ensuring the output format (such as ESM or CJS) meets target environment specifications. For example:

    {
      "module": "esm",
      "type": "module"
    }
    

Comparison Between Modules and Namespaces

TypeScript's module system differs from JavaScript namespaces; modules offer a more flexible organization approach, while namespaces are closer to the original ECMAScript syntax. Modules support complex dependency relationships and type systems, making them suitable for large-scale project architectures.