TypeScript + Node.js 実践

TypeScript は Node.js バックエンド開発で広く利用されています。本チュートリアルでは、Node.js プロジェクトにおける TypeScript の設定と使用方法を紹介します。

TypeScript を使用することで、Node.js コードの安全性が高まり、保守が容易になります。特に中規模・大規模なバックエンドプロジェクトに適しています。

Node.js チュートリアルはこちら:https://www.example.com/nodejs/nodejs-tutorial.html


SVG 図:Node.js + TypeScript プロジェクト構造 背景 タイトル Node.js + TypeScript プロジェクト構造 プロジェクト設定 プロジェクト設定 package.json tsconfig.json ts-node ソースコード ソースコード (src/) types/ - 型定義 services/ - ビジネスロジック routes/ - ルート処理 コンパイル出力 コンパイル出力 (dist/) .js - JavaScript .d.ts - 型宣言 .map - ソースマップ 実行時 Node.js 実行時 JS を実行 下半分:開発フロー 開発フロー ステップ1 npm install で依存関係をインストール ステップ2 tsc で TypeScript をコンパイル ステップ3 node で JavaScript を実行 ステップ4 API リクエストテスト 矢印マーク

なぜ Node.js で TypeScript を使う必要があるのか

Node.js プロジェクトは通常、複雑なビジネスロジックやデータ処理を伴うため、コード行数が急速に増加します。

TypeScript を使用すると:コンパイル時の型チェックにより実行時エラーを減らせます;IDE のインテリセンスにより開発効率が向上します;コードが読みやすく保守しやすくなります。

多くの大規模 Node.js プロジェクト(NestJS など)は TypeScript を推奨、またはデフォルトで使用しています。

利点:TypeScript の静的型チェックは開発中に潜在的な問題を発見できるため、実行時のデバッグよりも効率的です。


プロジェクト初期化

まず Node.js プロジェクトを初期化し、TypeScript 関連の依存関係をインストールします。

プロジェクトの初期化

# npm を初期化
npm init -y

# TypeScript と Node.js の型定義をインストールjs型定義
# --D は開発依存関係としてインストールすることを示します
npm install -D typescript @types/node ts-node nodemon

# tsconfig を初期化json
npx tsc --init

説明:@types/nodeNode.js API の型定義を提供し、ts-nodeTypeScript ファイルを直接実行でき、nodemonファイルの変更を監視して自動再起動します。


tsconfig.json の設定

TypeScript コンパイラのオプションを設定し、Node.js プロジェクト向けに最適化します。

tsconfig.json

{
    "compilerOptions": {
        // コンパイルターゲット:ES2020
        "target": "ES2020",

        // モジュールシステム:CommonJS(Node.js ネイティブサポート)
        "module": "commonjs",

        // 有効にするライブラリ
        "lib": ["ES2020"],

        // 出力ディレクトリ
        "outDir": "./dist",

        // ソースルートディレクトリ
        "rootDir": "./src",

        // 厳格モード(常に有効)
        "strict": true,

        // ES モジュール相互運用
        "esModuleInterop": true,

        // ライブラリチェックをスキップ
        "skipLibCheck": true,

        // ファイル名の大文字小文字を強制
        "forceConsistentCasingInFileNames": true,

        // モジュール解決戦略
        "moduleResolution": "node",

        // 宣言ファイルを生成
        "declaration": true
    },
    // コンパイル対象ファイル
    "include": ["src/**/*"],
    // 除外ファイル
    "exclude": ["node_modules", "dist"]
}

推奨設定:Node.js プロジェクトでは次を推奨します:module: "commonjs"これは Node.js がネイティブサポートするモジュールシステムです。


型の定義

types ディレクトリでプロジェクトの型インターフェースを定義します。

src/types/index.ts

// ユーザー型定義
export interface User {
    id: number;         // ユーザー ID
    name: string;       // ユーザー名
    email: string;      // メールアドレス
    createdAt: Date;   // 作成日時
}

// ユーザー作成用データ転送オブジェクト(DTO)
export interface CreateUserDTO {
    name: string;       // ユーザー名(必須)
    email: string;     // メールアドレス(必須)
    password: string;   // パスワード(必須)
}

// APIレスポンス型(ジェネリック)
export interface ApiResponse<T> {
    success: boolean;   // 成否
    data?: T;         // 成功時のデータ
    error?: string;   // 失敗時のエラーメッセージ
}

型定義:型定義を types ディレクトリに集中させると、保守と再利用が容易になります。


サービスの実装

services ディレクトリでビジネスロジックを実装し、定義済みの型を使用します。

src/services/userService.ts

// 型定義をインポート
import { User, CreateUserDTO, ApiResponse } from "../types";

// ユーザーサービスクラス
class UserService {
    // ユーザーリスト(メモリ内保存)
    private users: User[] = [];
    // 次のユーザー ID
    private nextId = 1;

    // ユーザー作成
    createUser(dto: CreateUserDTO): ApiResponse<User> {
        try {
            // ユーザーオブジェクトを作成
            const user: User = {
                id: this.nextId++,
                name: dto.name,
                email: dto.email,
                createdAt: new Date()
            };
            this.users.push(user);
            return { success: true, data: user };
        } catch (error) {
            return { success: false, error: ユーザーの作成に失敗しました };
        }
    }

    // 単一ユーザーの取得
    getUser(id: number): ApiResponse<User> {
        const user = this.users.find(u => u.id === id);
        if (!user) {
            return { success: false, error: ユーザーが存在しません };
        }
        return { success: true, data: user };
    }

    // 全ユーザーの取得
    getAllUsers(): ApiResponse<User[]> {
        return { success: true, data: this.users };
    }
}

// シングルトンをエクスポート
export default new UserService();

実行結果:

UserService 实例化成功

サービス層:ビジネスロジックを service 層に集約することで、テストと再利用が容易になります。


API ルートの作成

Express フレームワークを使用して RESTful API を作成します。

src/index.ts

import express, { Request, Response } from "express";
import userService from "./services/userService";

// Express アプリを作成
const app = express();
// JSON リクエストボディを解析
app.use(express.json());

// 全ユーザーの取得
app.get("/api/users", (req: Request, res: Response) => {
    const result = userService.getAllUsers();
    res.json(result);
});

// 単一ユーザーの取得
app.get("/api/users/:id", (req: Request, res: Response) => {
    const id = parseInt(req.params.id);
    const result = userService.getUser(id);
    res.json(result);
});

// ユーザー作成
app.post("/api/users", (req: Request, res: Response) => {
    const result = userService.createUser(req.body);
    res.json(result);
});

const PORT = 3000;
app.listen(PORT, () => {
    console.log(`サーバーは http で実行中://localhost:${PORT}`);
});

実行結果:

服务器运行在 http://localhost:3000

型ヒント:次の型をRequestとResponse使用すると、IDE が完全なプロパティヒントを提供します。


package.json のスクリプト

npm スクリプトを設定して開発フローを簡素化します。

package.json

{
    "scripts": {
        // TypeScript をコンパイル
        "build": "tsc",

        // コンパイルした JavaScript を実行
        "start": "node dist/index.js",

        // 開発モード:nodemon で変更を監視して自動再起動
        "dev": "nodemon --exec ts-node src/index.ts",

        // テストを実行
        "test": "jest"
    }
}

開発効率:を使用すると、npm run devコード変更後にサーバーを自動再起動できます。


注意事項

  • 厳格モード:常に strict: true を有効にする
  • モジュール選択:Node.js プロジェクトでは commonjs を使用
  • 型定義:@types/node をインストールして API 型を取得する
  • 開発ツール:ts-node を使用してホットリロードを実現する

ベストプラクティス:型定義とビジネスロジックを分離しておくと、テストと保守が容易になります。


まとめ

TypeScript は Node.js バックエンド開発の優れた選択肢です。

  • プロジェクト設定:tsconfig.json を使用してコンパイルオプションを設定
  • 型定義:types ディレクトリでインターフェースを一元管理
  • サービス層:ビジネスロジックとルートを分離
  • ルート:Express を使用して RESTful API を作成
  • 開発ツール:ts-node、nodemon で開発効率を向上

提案:新規プロジェクトは TypeScript を直接使用し、既存プロジェクトは段階的に移行できます。

その他の拡張