TypeScript 速習チュートリアル

TypeScript のツールチェーン

1. TypeScript開発のエコシステム

TypeScriptのツールエコシステムは、その最大の強みの1つです。開発のあらゆるステージにおいて、開発者に強力なツールを提供します。

  • コードの品質(Code Quality)
    • TypeScriptをサポートするESLint
    • 型チェックとリンティング
    • コードスタイルの強制
  • 開発(Development)
    • VS Codeとの統合
    • デバッグツール
    • ホットモジュールリプレイスメント (HMR)
  • ビルドとデプロイ(Build & Deploy)
    • バンドラー(Vite, Webpack, Parcel)
    • モジュールのバンドル
    • 本番環境の最適化

2. ESLintによるリンティング

2.1 インストール

ESLintがTypeScriptの構文とルールを理解できるように、ESLint本体と公式のTypeScriptプラグイン/パーサーをインストールします。

例:独自のTypeScriptサーバーを構築する

# TypeScriptサポートを含むESLintをインストール
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

2.2 設定

この設定では、TypeScript向けの推奨ESLintルールを有効にし、型情報を活用したリンティング(type-aware linting)を行うためにESLintを tsconfig に接続し、いくつかの一般的なルールを調整します。

例:

// .eslintrc.json
{
  "root": true,
  "parser": "@typescript-eslint/parser",
  "plugins": ["@typescript-eslint"],
  "extends": [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking"
  ],
  "parserOptions": {
    "project": "./tsconfig.json",
    "ecmaVersion": 2020,
    "sourceType": "module"
  },
  "rules": {
    "@typescript-eslint/explicit-function-return-type": "warn",
    "@typescript-eslint/no-explicit-any": "warn",
    "@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }]
  }
}

2.3 NPMスクリプト

リンティングと型チェックのみの実行を行うスクリプトを追加します。簡単な問題は lint:fix で自動修正できます。

例:

// package.json
{
  "scripts": {
    "lint": "eslint . --ext .ts,.tsx",
    "lint:fix": "eslint . --ext .ts,.tsx --fix",
    "type-check": "tsc --noEmit"
  }
}

3. Prettierによるコード整形

Prettierは、チーム全体で一貫したコードスタイルを強制します。ESLintと組み合わせて使用することで、フォーマット関連のリンティングエラーを回避できます。

3.1 インストール

Prettierと、競合するルールを無効化し、フォーマットの問題をESLint経由で報告するためのプラグインをインストールします。

例:

# Prettierと関連パッケージのインストール
npm install --save-dev prettier eslint-config-prettier eslint-plugin-prettier

3.2 設定

.prettierrc でPrettierの好みを定義し、.prettierignore で生成されたフォルダーを無視するように設定します。

例:

// .prettierrc
{
  "semi": true,
  "singleQuote": true,
  "tabWidth": 2,
  "printWidth": 100,
  "trailingComma": "es5",
  "bracketSpacing": true,
  "arrowParens": "avoid"
}

// .prettierignore
node_modules
build
dist
.next
.vscode

3.3 ESLintとの統合

フォーマットの問題がESLintの問題として報告されるように、plugin:prettier/recommended を継承します。

例:

// .eslintrc.json
{
  "extends": [
    // ... 他の設定
    "plugin:prettier/recommended" // 配列の最後に配置する必要があります
  ]
}

例:PrettierをESLintに統合する

npm install --save-dev eslint-config-prettier eslint-plugin-prettier
# .eslintrc.js または .eslintrc.json に以下を追加:
{
  "extends": ["plugin:prettier/recommended"]
}

4. モダンなビルドツール

高速な開発サーバーとモダンなビルドには Vite が推奨されます。Webpack も一般的であり、高度なカスタマイズが可能です。

4.1 Vite(推奨)

Viteを使用して新しいReact + TypeScriptプロジェクトを作成します。高速なフィードバックを得るためのHMRを備えた開発サーバーを起動します。

例:

# React + TypeScriptで新しいプロジェクトを作成
npm create vite@latest my-app -- --template react-ts

# プロジェクトディレクトリに移動
cd my-app

# 依存関係のインストール
npm install

# 開発サーバーの起動
npm run dev

4.2 Webpackの設定

Webpackを選択する場合、以下の最小限のセットアップでTypeScriptをトランスパイルし、CSSを処理し、webpack-dev-server でアプリを提供できます。

例:

// webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: './src/index.tsx',
  module: {
    rules: [
      {
        test: /\.(ts|tsx)$/,
        use: 'ts-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        use: ['style-loader', 'css-loader'],
      },
    ],
  },
  resolve: {
    extensions: ['.tsx', '.ts', '.js'],
  },
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, 'dist'),
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './public/index.html',
    }),
  ],
  devServer: {
    static: path.join(__dirname, 'dist'),
    compress: true,
    port: 3000,
    hot: true,
  },
};

5. TypeScriptの設定 (tsconfig.json)

モダンブラウザをターゲットにした厳格な tsconfig.json の設定です。オプションの baseUrlpaths は、@/components/Button のような絶対パスでのインポート(パスエイリアス)に役立ちます。

例:

// tsconfig.json
{
  "compilerOptions": {
    "target": "es2020",
    "module": "esnext",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    }
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

6. 開発環境のセットアップ

エディタを設定して、リンティングエラーを表示し、保存時にフォーマットし、効率的にデバッグできるようにします。

6.1 VS Code 拡張機能

VS Codeの推奨拡張機能:

  • TypeScript + Webpack Problem Matchers - より良いエラー報告のため
  • ESLint - ESLintをVS Codeに統合
  • Prettier - Code formatter - 一貫したコード整形のため
  • Path IntelliSense - ファイル名の自動補完
  • Error Lens - エラーを行内に直接表示

6.2 VS Code 設定

Prettierをデフォルトのフォーマッターとして使用し、保存時にESLintの問題を修正し、相対パスではないインポートパスを優先するように設定します。

例:

// .vscode/settings.json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "editor.formatOnSave": true,
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true,
    "source.organizeImports": true
  },
  "eslint.validate": ["javascript", "javascriptreact", "typescript", "typescriptreact"],
  "typescript.tsdk": "node_modules/typescript/lib",
  "typescript.preferences.importModuleSpecifier": "non-relative"
}

6.3 デバッグ設定

開発サーバーに対してChromeを起動し、VS Codeから直接Nodeベースのテストデバッグを実行します。

例:

// .vscode/launch.json
{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "chrome",
      "request": "launch",
      "name": "Launch Chrome against localhost",
      "url": "http://localhost:3000",
      "webRoot": "${workspaceFolder}",
      "sourceMaps": true,
      "sourceMapPathOverrides": {
        "webpack:///./~/*": "${workspaceFolder}/node_modules/*",
        "webpack:///./*": "${workspaceFolder}/src/*"
      }
    },
    {
      "type": "node",
      "request": "launch",
      "name": "Debug Tests",
      "runtimeExecutable": "${workspaceRoot}/node_modules/.bin/jest",
      "args": ["--runInBand", "--watchAll=false"],
      "console": "integratedTerminal",
      "internalConsoleOptions": "neverOpen",
      "sourceMaps": true
    }
  ]
}

7. テスト環境の構築

React + TypeScriptアプリのテストには、JestとTesting Libraryの組み合わせが一般的です。

7.1 Jest + Testing Library

Jest、TypeScriptサポート、およびDOMアサーションとユーザーインタラクションのためのReact Testing Libraryユーティリティをインストールします。

例:

# テスト用の依存関係をインストール
npm install --save-dev jest @types/jest ts-jest @testing-library/react @testing-library/jest-dom @testing-library/user-event

7.2 Jestの設定

ts-jest を使用し、CSSモジュールをマップし、@/ のようなエイリアスパスを解決するようにJestを設定します。

例:

// jest.config.js
module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'jsdom',
  setupFilesAfterEnv: ['@testing-library/jest-dom'],
  moduleNameMapper: {
    '^@/(.*)$': '<rootDir>/src/$1',
    '\\.(css|less|scss|sass)$': 'identity-obj-proxy',
  },
  transform: {
    '^.+\\.tsx?$': 'ts-jest',
  },
  testMatch: ['**/__tests__/**/*.test.(ts|tsx)'],
};

7.3 テストの例

Testing Libraryを使用して、レンダリングとクリック時の動作を検証するシンプルなコンポーネントテストです。

例:

// src/__tests__/Button.test.tsx
import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import '@testing-library/jest-dom';
import Button from '../components/Button';

describe('Button', () => {
  it('正しいテキストでボタンをレンダリングする', () => {
    render(<Button>クリックしてね</Button>);
    expect(screen.getByRole('button', { name: /クリックしてね/i })).toBeInTheDocument();
  });

  it('クリックされた時にonClickを呼び出す', () => {
    const handleClick = jest.fn();
    render(<Button onClick={handleClick}>クリックしてね</Button>);
    
    fireEvent.click(screen.getByRole('button'));
    expect(handleClick).toHaveBeenCalledTimes(1);
  });
});

8. ベストプラクティス

8.1 開発ワークフロー

  • ホットリロードを使用した開発には npm run dev を使用する
  • TypeScriptの型を検証するには npm run type-check を実行する
  • リンティングエラーを確認するには npm run lint を使用する
  • 本番用ビルドを作成するには npm run build を実行する

8.2 パフォーマンスの最適化

  • ダイナミックインポートによるコード分割(Code splitting)を使用する
  • 本番ビルドでのツリーシェイキング(Tree-shaking)を有効にする
  • 負荷の高い計算には React.memouseMemo を使用する
  • クリティカルでないコンポーネントを遅延読み込み(Lazy load)する

8.3 よくある落とし穴

  • TypeScript設定: strict モードが有効であることを確認してください
  • ESLint + Prettier の競合: eslint-config-prettier を使用して競合するルールを無効化してください
  • ビルドが遅い: より高速な開発のためにViteやesbuildの導入を検討してください
  • 型定義の不足: すべての依存関係に対して @types パッケージをインストールしてください
  • デバッグの問題: ソースマップが正しく設定されていることを確認してください

8.4 推奨ツール

  • バンドラー: Vite, Webpack, Parcel
  • テスト: Jest, React Testing Library, Cypress
  • リンティング/フォーマット: ESLint, Prettier, Stylelint
  • ドキュメンテーション: TypeDoc, Storybook
  • パフォーマンス: Web Vitals, Lighthouse