コンテンツにスキップ

Chapter 5: TypeScript 入門

TypeScript は JavaScript に型の仕組みを加えた言語です。
型を明示すると,コードの意図が伝わりやすくなり,バグの早期発見にもつながります。Next.js でも標準的に採用されているため,ここで基礎を押さえておきましょう。


TypeScript を導入する

  1. 作業用フォルダ(例:fes-training/javascript/ts-intro)を作成。
  2. npm プロジェクトを初期化し,TypeScript を追加します。
npm init -y
npm install --save-dev typescript
npx tsc --init
  1. tsconfig.json が生成されます。以下の設定を確認・変更しておきましょう。
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ES2020",
    "moduleResolution": "node",
    "outDir": "dist",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src"]
}
  1. src フォルダを作り,index.ts を作成します。
type StaffRole = "system" | "design" | "publicity";

interface Staff {
  id: number;
  name: string;
  role: StaffRole;
  skills: string[];
}

const members: Staff[] = [
  { id: 1, name: "山田 太郎", role: "system", skills: ["React", "Git"] },
  { id: 2, name: "佐藤 花子", role: "design", skills: ["Figma", "HTML"] },
];

function findMembersByRole(role: StaffRole): Staff[] {
  return members.filter((member) => member.role === role);
}

console.log(findMembersByRole("system"));
  1. コンパイルして実行します。
npx tsc
node dist/index.js

基本的な型

説明
string "Hello" 文字列
number 42 数値(整数・小数)
boolean true 真偽値
Array<T> string[] 配列
object { name: "Chibafes" } オブジェクト
union "draft" \| "published" いずれかの値

TypeScript は型推論が賢いため,明示しなくても推論されることが多いです。ただし,関数の引数や戻り値には型を付ける習慣を付けましょう。


ユニオンと型エイリアス

type Status = "draft" | "published" | "archived";

function updateStatus(status: Status) {
  if (status === "draft") {
    console.log("編集可能です。");
  } else if (status === "published") {
    console.log("公開中です。");
  }
}

updateStatus("draft");
// updateStatus("unknown"); // エラー

型エイリアス(type)を使うと,複雑な型定義を再利用しやすくなります。


Generics(ジェネリクス)

型の一部を引数として受け取れる仕組みです。

function createList<T>(items: T[]): T[] {
  return [...items];
}

const numbers = createList([1, 2, 3]);
const names = createList(["前夜祭", "本祭"]);

ジェネリクスは React Hooks や API 呼び出しのラッパーなどで頻繁に登場します。


ハンズオン:スタッフ管理ユーティリティ

  1. src/staff.ts を作成し,Staff インターフェースを定義。
  2. メンバーを追加・削除・検索する関数を実装します。
interface Staff {
  id: number;
  name: string;
  role: "system" | "design" | "publicity";
  joinedAt: Date;
}

const database: Staff[] = [];

export function addStaff(staff: Staff) {
  database.push(staff);
  return database.length;
}

export function getStaffByRole(role: Staff["role"]) {
  return database.filter((staff) => staff.role === role);
}
  1. src/index.ts から利用します。
import { addStaff, getStaffByRole } from "./staff.js";

addStaff({
  id: 1,
  name: "田中 一郎",
  role: "system",
  joinedAt: new Date(),
});

console.log(getStaffByRole("system"));
  1. npx tsc --watch を使うと保存時に自動で再コンパイルされます。

TypeScript + ESLint

Chapter 3 で導入した ESLint を TypeScript 対応にするには,追加のパッケージが必要です。

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin

.eslintrc.json の例:

{
  "parser": "@typescript-eslint/parser",
  "parserOptions": { "ecmaVersion": "latest", "sourceType": "module" },
  "plugins": ["@typescript-eslint"],
  "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
  "ignorePatterns": ["dist"]
}

練習課題

  • Staffskills: string[] を追加し,スキルで検索できる関数を実装。
  • API から取得したデータ(Chapter 4)に TypeScript の型を付けてみましょう。レスポンスの構造を type で表現します。
  • readonly 修飾子を使い,変更してはいけないプロパティを保護してみましょう。

次のステップ

TypeScript の基礎を押さえたら,React / Next.js の章でコンポーネント開発に挑戦しましょう。
ここまでのコードは GitHub に push し,学習の記録として残しておくと役立ちます。