TypeScriptでコードを構造化する方法として、「名前空間(namespace)」と「モジュール」の2つのアプローチがあります。これらの違いと適切な使い分けについて解説します。

名前空間(namespace)とは

名前空間は、TypeScriptの古い機能で、以前は「内部モジュール」と呼ばれていました。コードを論理的なグループに分類するために使用されます。

namespace Mathematics {
    export function add(x: number, y: number): number {
        return x + y;
    }
    
    export function subtract(x: number, y: number): number {
        return x - y;
    }
}

// 使用例
console.log(Mathematics.add(5, 3)); // 8

モジュール(ESモジュール)とは

モジュールは、ECMAScript 2015で導入された標準的なモジュールシステムです。ファイルレベルのスコープを持ち、明示的なエクスポート/インポート構文を使用します。

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

export function subtract(x: number, y: number): number {
    return x - y;
}

// main.ts
import { add, subtract } from './math';
console.log(add(5, 3)); // 8

使い分けのガイドライン

名前空間を使うべき場合

  • レガシーコードの保守
  • ブラウザで直接実行する必要があるスクリプト
  • 単一ファイルでの名前の衝突を避けたい場合

モジュールを使うべき場合

  • 新規プロジェクト
  • Node.jsアプリケーション
  • モダンなフロントエンド開発
  • バンドラー(webpack, Rollupなど)を使用する場合

それぞれのメリット・デメリット

名前空間のメリット

  • シンプルな構文
  • ブラウザでの直接実行が容易
  • 単一ファイルでの名前衝突の回避

名前空間のデメリット

  • 依存関係の管理が難しい
  • バンドル時の最適化が困難
  • モダンな開発ツールとの相性が悪い

モジュールのメリット

  • 明示的な依存関係
  • 木構造の削除(tree-shaking)が可能
  • モダンな開発ツールとの互換性
  • より良いIDE支援

モジュールのデメリット

  • バンドラーが必要
  • 設定が必要な場合がある
  • ブラウザでの直接実行には追加の設定が必要

ベストプラクティス

1. 新規プロジェクトではESモジュールを使用する

2. 名前空間は既存のプロジェクトの保守用として考える

3. モジュールを使用する際は、1ファイル1モジュールの原則を守る

4. 適切な依存関係管理のためにpackage.jsonを活用する

まとめ

現代のTypeScript開発では、ESモジュールの使用が推奨されています。名前空間は下位互換性のために残されている機能と考え、新規開発では可能な限りモジュールを使用することをお勧めします。ただし、プロジェクトの要件や制約に応じて、適切な方式を選択することが重要です。