0Pricing
TypeScript Academy · レッスン

共有型パッケージの戦略

monorepo全体で利用する専用の型パッケージを作成します。

「共有型パッケージの戦略」はCoddyKit上の無料TypeScript Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはTypeScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 TypeScript Academyコースには全4レッスンが含まれています。

共有型パッケージが必要な理由

フロントエンドとバックエンドで型を共有すると、API コントラクトのずれをなくせます。単一の信頼できる情報源を持つことで、API の形状が変わったときにコンパイル時エラーが発生します。

// packages/types/src/index.ts
export interface User { id: string; name: string; email: string; }
export interface ApiResponse<T> { data: T; error?: string; }

パッケージ構造

型パッケージは、型のエクスポートだけを含む最小限の構成にし、実行時ロジックは含めません。これにより副作用がなく、tree-shaking 可能になります。

packages/types/
├── src/
│   ├── index.ts      # re-exports all
│   ├── user.ts
│   ├── product.ts
│   └── api.ts
├── tsconfig.json
└── package.json

型パッケージ用の tsconfig

emitDeclarationOnly を有効にすると、JavaScript は出力されず、利用側が参照する .d.ts ファイルだけが生成されます。

{
  "compilerOptions": {
    "composite": true,
    "declaration": true,
    "emitDeclarationOnly": true,
    "outDir": "./dist",
    "rootDir": "./src"
  }
}

型パッケージの利用

API と Web アプリの両方で型パッケージを参照し、実行時のオーバーヘッドを避けるために import type で型をインポートします。

import type { User, ApiResponse } from "@myapp/types";

async function getUser(id: string): Promise<ApiResponse<User>> {
  // ...
}

シリアライズ可能な型の維持

クライアントとサーバーで共有する型には、JSON にシリアライズ可能な値だけを含めます。Date オブジェクトは避け、代わりに string(ISO 形式)を使用します。

// Good: serialization-safe
interface Event { id: string; createdAt: string; /* ISO date */ }
// Bad: Date is not JSON-serializable
interface Event { id: string; createdAt: Date; }

型パッケージのバージョン管理

型パッケージを semver でバージョン管理します。フィールドの削除や名前変更などの破壊的変更では、メジャーバージョンを上げます。

# Breaking change: major bump
npm version major
# Adding optional fields: minor bump
npm version minor

OpenAPI からの型生成

openapi-typescript を使用して OpenAPI 仕様から型パッケージを生成し、作成を自動化します。これにより、型が常にバックエンドと一致します。

npx openapi-typescript ./api/openapi.yaml -o ./packages/types/src/api.ts

Zod による実行時型とコンパイル時型の利用

Zod スキーマで型を定義し、そこから TypeScript の型を推論します。実行時のバリデーションと静的型の両方を同じソースから取得できます。

import { z } from "zod";
export const UserSchema = z.object({ id: z.string(), name: z.string() });
export type User = z.infer<typeof UserSchema>;

循環依存の回避

循環依存の連鎖を防ぐため、型パッケージから他のワークスペースパッケージをインポートしないようにします。依存関係グラフのリーフノードとして維持します。

// types/ should not import from ui/ or api/
// ui/ and api/ both import from types/

型の正しさのテスト

tsd を使用して型レベルのアサーションを記述し、共有型が期待どおりであることを検証します。

import { expectType } from "tsd";
import type { User } from "@myapp/types";
expectType<User>({ id: "1", name: "Alice", email: "a@b.com" });

まとめ: 共有型の戦略

共有型パッケージは API のずれをなくします。宣言ファイルだけを出力し、型を JSON にシリアライズ可能に保ち、semver でバージョン管理します。必要に応じて OpenAPI から自動生成し、tsd でテストします。

確認問題

共有 API 型では、なぜ Date ではなく string を使用するべきですか。

学んだこと

共有型パッケージは、API コントラクトにおける単一の信頼できる情報源です。宣言ファイルだけを出力し、JSON に対応できる状態を保ち、semver でバージョン管理します。必要に応じて OpenAPI から生成することで、フロントエンドとバックエンドのずれをなくせます。

よくある質問

「共有型パッケージの戦略」レッスンは無料ですか?

はい。「共有型パッケージの戦略」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、TypeScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 TypeScript Academyコースには全4レッスンが含まれています。

「共有型パッケージの戦略」で何を学びますか?

monorepo全体で利用する専用の型パッケージを作成します。 ブラウザで直接実行するハンズオンコードでTypeScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

TypeScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのTypeScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。

「共有型パッケージの戦略」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このTypeScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのTypeScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. TypeScriptプロジェクト参照の解説
  2. TypeScriptでのpnpm Workspaces
  3. 共有型パッケージの戦略
  4. MonorepoのIncremental BuildとCache
← TypeScript Academyに戻る