NodeJS 速習チュートリアル

Node.js TypeScript

1. TypeScript とは?

TypeScript は、JavaScript に「オプションの静的型付け(Static Typing)」を追加したスーパーセットです。
開発の早い段階でエラーをキャッチし、より安全でメンテナンス性の高いコードを書くのに役立ちます。

Node.js プロジェクトに TypeScript を導入することで、動的型付け特有の「実行してみるまでわからないバグ」を劇的に減らすことができます。

2. Node.js での TypeScript の利用

Node.js 環境で TypeScript を動かすには、TypeScript コンパイラ本体と Node.js 用の型定義マネージャーをインストールする必要があります。

# TypeScript をグローバルにインストール
npm install -g typescript

# Node.js の型定義を開発依存関係としてインストール
npm install --save-dev @types/node

.ts ファイルにコードを記述し、以下のコマンドで JavaScript にコンパイルします:

tsc yourfile.ts

3. TypeScript プロジェクトのセットアップ

Node.js で本格的なプロジェクトを開始するための標準的な手順は以下の通りです。

3.1 手順 1:新しい Node.js プロジェクトの初期化

npm init -y

3.2 手順 2:TypeScript と型定義のインストール

npm install --save-dev typescript @types/node

3.3 手順 3:TypeScript 設定ファイルの初期化

npx tsc --init

これにより、プロジェクトのルートに tsconfig.json が生成されます。

4. TypeScript の基本構文

4.1 基本の型(Basic Types)

// プリミティブ型
let isDone: boolean = false;
let count: number = 10;
let name: string = 'TypeScript';

// 配列
let numbers: number[] = [1, 2, 3];
let names: Array<string> = ['Alice', 'Bob'];

// タプル(要素数と型が固定された配列)
let user: [string, number] = ['Alice', 25];

// 列挙型(Enums)
enum Color {Red, Green, Blue}
let color: Color = Color.Green;

4.2 インターフェース(Interfaces)と型エイリアス(Types)

// インターフェースの定義
interface User {
  id: number;
  name: string;
  email?: string; // ? をつけるとオプションプロパティになる
}

// 型エイリアス
type Point = {
  x: number;
  y: number;
};

// インターフェースの使用例
function printUser(user: User) {
  console.log(`ユーザー名: ${user.name}`);
}

5. Node.js での TypeScript 実践

5.1 シンプルな HTTP サーバーの作成

TypeScript で標準の http モジュールを使用する例です。

// server.ts
import http from 'http';

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain; charset=utf-8');
  res.end('こんにちは、TypeScript!');
});

const PORT = process.env.PORT || 3000;
server.listen(PORT, () => {
  console.log(`サーバーがポート ${PORT} で起動しました`);
});

5.2 Express と TypeScript の組み合わせ

Express を使用する場合は、Express 本体の他に型定義ファイル(@types/express)が必要です。

# 必要なパッケージのインストール
npm install express
npm install --save-dev @types/express
// app.ts
import express, { Request, Response } from 'express';

interface User {
  id: number;
  name: string;
}

const app = express();
app.use(express.json());

// インメモリデータベースのシミュレーション
let users: User[] = [];

// 全ユーザーの取得
app.get('/users', (req: Request, res: Response) => {
  res.json(users);
});

// 新規ユーザーの追加
app.post('/users', (req: Request, res: Response) => {
  const user: User = req.body;
  users.push(user);
  res.status(201).json(user);
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Express サーバーがポート ${PORT} で起動しました`);
});

6. TypeScript の設定:tsconfig.json

tsconfig.json は、コンパイルの挙動を詳細に制御するための重要なファイルです。Node.js 開発における推奨設定の例を以下に示します。

{
  "compilerOptions": {
    "target": "es2018",      // コンパイル後の JavaScript バージョン
    "module": "commonjs",    // モジュール形式(Node.js の場合は通常 commonjs)
    "outDir": "./dist",      // コンパイル後のファイルの出力先
    "rootDir": "./src",      // ソースファイルのディレクトリ
    "strict": true,          // すべての厳密な型チェックを有効化
    "esModuleInterop": true, // CommonJS と ES Modules 間の互換性を確保
    "skipLibCheck": true,    // 型定義ファイルのチェックをスキップ(ビルド高速化)
    "forceConsistentCasingInFileNames": true // ファイル名の大文字小文字を区別
  },
  "include": ["src/**/*"],   // コンパイル対象に含めるファイル
  "exclude": ["node_modules"] // 除外するファイル
}

7. なぜ Node.js で TypeScript を使うのか?

7.1 TypeScript のメリット

  • 型安全性(Type Safety): 実行時ではなく、コンパイル時にエラーを検出できます。
  • 強力な IDE サポート: インテリセンス(自動補完)やコードナビゲーションが飛躍的に向上します。
  • 自己ドキュメント化: 型自体がドキュメントの役割を果たし、コードの意図が明確になります。
  • リファクタリングの容易さ: 変数名の変更やコードのアップデートを安全に行えます。
  • 段階的な導入: 既存の JavaScript コードに少しずつ型を追加していくことが可能です。

7.2 TypeScript を使うべきタイミング

  • 複数の開発者が関わる大規模なコードベース
  • 型の不整合が重大なバグにつながる API 開発
  • 長期間にわたってメンテナンスが必要なプロジェクト
  • 複雑なデータ構造を扱うアプリケーション

TypeScript は、モダンな Node.js 開発において「あれば便利」なものではなく、プロフェッショナルな現場では「必須」に近いツールとなっています。最初は少し学習コストがかかりますが、将来のデバッグ時間を大幅に節約できる投資と言えるでしょう。