TypeScript 完全実践ガイド〜型システム・ジェネリクス・ユーティリティ型・React+TypeScript【2026年版】〜

TypeScript——もはやモダンJavaScript開発の事実上の標準。React・Vue・Next.js・Node.jsの新規プロジェクトの90%以上がTypeScriptで書かれる現代において、TypeScriptの型システムを使いこなすことは、Webエンジニアの必須スキルだ。本記事では、初心者から経験者まで使えるTypeScript実践テクニックを体系的に解説する。

TypeScript基本型システム

プリミティブ型

let name: string = "Alice";
let age: number = 30;
let isActive: boolean = true;
let value: null | undefined;
let id: number | string; // ユニオン型

配列・オブジェクト型

let items: string[] = ["a", "b"];
let users: Array = [];
let config: { host: string; port: number } = { host: "localhost", port: 3000 };

type と interface の使い分け

type(型エイリアス)

type User = {
  id: number;
  name: string;
};

type UserOrAdmin = User | Admin; // ユニオン型・交差型に強い

interface

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

interface User { // 同名で拡張可能(declaration merging)
  email: string;
}

使い分けのガイドライン

  • type: ユニオン型・交差型・関数型・タプル型を扱う場合
  • interface: クラスやオブジェクトの「形状」を定義する場合・拡張性を重視
  • 2024年現代: typeを優先するのがコミュニティの一般的傾向

ジェネリクスの活用

「型を引数として扱う」機能。汎用的な関数・クラス・コンポーネントを作るために必須。

function identity<T>(value: T): T {
  return value;
}

identity<string>("hello"); // string型
identity<number>(42); // number型

Reactコンポーネントでの活用例:

interface Props<T> {
  items: T[];
  renderItem: (item: T) => React.ReactNode;
}

function List<T>({ items, renderItem }: Props<T>) {
  return items.map(renderItem);
}

ユーティリティ型

  • Partial<T>: 全プロパティをオプショナルに
  • Required<T>: 全プロパティを必須に
  • Pick<T, K>: 特定キーのみ抽出
  • Omit<T, K>: 特定キーを除外
  • Record<K, T>: キーと値の型を指定
  • ReturnType<T>: 関数の戻り値型
  • Parameters<T>: 関数の引数型
  • Awaited<T>: PromiseのT型を取り出す

高度な型システム

条件型(Conditional Types)

type IsString<T> = T extends string ? true : false;
type A = IsString<"hello">; // true
type B = IsString<42>; // false

マップ型(Mapped Types)

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

テンプレートリテラル型

type Greeting = `Hello, ${string}`;
type EventName = `on${'Click' | 'Hover'}`;

型の絞り込み(Type Narrowing)

typeof による絞り込み

function format(value: string | number) {
  if (typeof value === "string") {
    return value.toUpperCase(); // valueはstring
  }
  return value.toFixed(2); // valueはnumber
}

カスタム型ガード

function isUser(obj: any): obj is User {
  return obj && typeof obj.id === 'number' && typeof obj.name === 'string';
}

strict mode の活用

tsconfig.json で“strict”: trueを必ず設定。これにより全てのstrict系オプションが有効化:

  • strictNullChecks: null/undefinedの厳密チェック
  • strictFunctionTypes: 関数型の厳密チェック
  • strictPropertyInitialization: クラスプロパティ初期化チェック
  • noImplicitAny: 暗黙のany禁止
  • noImplicitThis: thisの暗黙any禁止

React+TypeScriptパターン

関数コンポーネントの型付け

interface ButtonProps {
  label: string;
  onClick: () => void;
  disabled?: boolean;
}

function Button({ label, onClick, disabled = false }: ButtonProps) {
  return <button onClick={onClick} disabled={disabled}>{label}</button>;
}

useStateの型推論

// 型推論を活用
const [count, setCount] = useState(0); // number型と推論

// 明示的指定
const [user, setUser] = useState<User | null>(null);

イベントハンドラー型

const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
  console.log(e.target.value);
};

const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => { /* ... */ };

TypeScript設定の推奨

推奨tsconfig.json

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "ESNext",
    "moduleResolution": "bundler",
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "exactOptionalPropertyTypes": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}

よくある型エラーと解決

  • “Property X does not exist on type Y”: オプショナルプロパティ・型ガード使用
  • “Type ‘X’ is not assignable to type ‘Y'”: 型のミスマッチ・キャスト不要かを再確認
  • “Object is possibly null”: null チェック・Optional Chaining(?.)使用
  • “Cannot find module ‘X'”: 型定義パッケージ(@types/X)インストール

TypeScriptツールチェーン

  • VS Code: TypeScript標準サポート・最強の開発体験
  • tsc: 公式コンパイラ
  • tsx: TypeScript直接実行(開発用)
  • esbuild / SWC: 超高速トランスパイル(本番ビルド用)
  • Biome / Prettier: コード整形
  • ESLint + typescript-eslint: コード品質チェック

よくある質問

Q. JavaScriptからTypeScriptへの移行は?

段階的移行が現実的。① .js.tsに拡張子変更、② allowJs: trueでJSとTSを共存、③ strict: falseで開始、④ 段階的にstrictオプションを有効化、⑤ 全ファイルがTS化したらstrict: trueに。1-3ヶ月の移行期間が一般的。

Q. any型は使ってもいい?

原則として避けるべき。unknown型(型ガードで絞り込み必要)を代替に使う。anyを使う場合は// eslint-disable-next-lineでコメント付きの明示的な使用を推奨。

Q. 型定義ファイル(.d.ts)とは?

JavaScript ライブラリにTypeScript の型情報を提供するファイル。@types/Xパッケージとして公開されているライブラリも多い(例: @types/react、@types/node)。自作の.d.tsで独自型を定義することも可能。

Q. TypeScriptは何で実行する?

開発時: tsx(高速TypeScript実行)または ts-node。本番ビルド: esbuild / SWC(超高速)で.tsを.jsにトランスパイル。Webアプリでは Vite・Next.js等のバンドラーが自動処理。

Q. 型レベルプログラミングってどこまでやるべき?

実務では「型エラーが起きにくい・型補完が効く」レベルで十分。複雑な条件型・マップ型は学習価値ありますが、過剰な型レベルロジックはコード保守性を下げます。シンプルさを優先するのが現代の主流。

あなたのTypeScript学習 5ステップ

  • STEP 1: 公式ドキュメント(typescriptlang.org)で基礎
  • STEP 2: 既存JSプロジェクトをTS化(段階的)
  • STEP 3: ユーティリティ型・ジェネリクス活用
  • STEP 4: 型ガード・型レベルプログラミング
  • STEP 5: 型ライブラリ(zod・io-ts等)で実用

関連記事「React Hooks完全実践ガイド」もご参考に。

コメント

タイトルとURLをコピーしました