effect-ts-fundamentals について
複雑な TypeScript アプリケーションを開発する人向けの Effect-TS 基礎スキルです。型付きエフェクト、依存性注入、非同期処理の合成を扱います。
主な機能
- 01ジェネレーターによるエフェクト合成
- 02型安全なサービス定義
- 03Layer による依存性注入
- 04宣言的な非同期パイプライン
活用シーン
- 01複雑な TypeScript アプリケーションの構築
- 02依存する非同期処理の合成
- 03サービスと実装の分離
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mrevanzak/ effect-ts-skills --skill effect-ts-fundamentalsインストール後、Claude Code で/effect-ts-fundamentalsを入力して読み込まれたか確認します。
詳細
Effect-TS の基礎
概要
Effect-TS は、副作用を値として扱うことで、堅牢なアプリケーションを構築するための統一されたツールキットを提供します。型安全なエラー処理、依存性注入、リソース管理を実現します。
使用する場面
- 厳密なエラー追跡が必要な複雑な TypeScript アプリケーションを構築する場合。
- 依存性注入を通じて実装とインターフェースを分離する必要がある場合。
- 安全に合成する必要がある複数の非同期処理を管理する場合。
使用しない場面:
- 標準の
Promiseとtry/catchで十分な単純なスクリプト。 - Effect の学習にかかるチームの負担が、アーキテクチャ上のメリットを上回るプロジェクト。
基本パターン
Effect は、手動での依存関係の受け渡しやネストした try/catch を、宣言的なジェネレーターベースのフローに置き換えます。
変更前(通常の TS):
async function getUserData(userId: string, db: Database) {
try {
const user = await db.findUser(userId);
const posts = await fetchPosts(user.id);
return { user, posts };
} catch (e) {
throw new Error("Failed");
}
}
変更後(Effect):
const getUserData = (userId: string) =>
Effect.gen(function* () {
const db = yield* DatabaseService;
const user = yield* db.findUser(userId);
const posts = yield* fetchPosts(user.id);
return { user, posts };
});
クイックリファレンス
| 機能 | ツール | 目的 |
|---|---|---|
| 順次処理 | Effect.gen | 読みやすい非同期パイプライン |
| サービス定義 | Effect.Service | 型安全な DI コンテナー |
| レイヤーの合成 | Layer.merge/provide | 依存関係の配線 |
実装
1. モダンなサービスパターン
組み込みアクセサーを備えたサービスを定義し、依存性注入をシームレスに行います。
export class UserService extends Effect.Service<UserService>()("UserService", {
accessors: true,
effect: Effect.gen(function* () {
const db = yield* DatabaseService;
return {
getUser: (id: string) => db.query(`SELECT * FROM users WHERE id = ${id}`)
};
}),
dependencies: [DatabaseService.Default]
}) {}
2. ジェネレーターによる順次処理
Effect.gen と yield* を使って、コールバック地獄や手動での Promise チェーンを避けながらエフェクトを合成します。
const getUserData = (userId: number) =>
Effect.gen(function* () {
const user = yield* fetchUser(userId);
const posts = yield* fetchUserPosts(user.id);
return { user, posts };
});
3. レイヤーベースの依存性注入
実装レイヤーを合成し、プログラムに提供します。
const MainLayer = Layer.merge(DatabaseService.Default, LoggerService.Default);
const program = pipe(myEffect, Effect.provide(MainLayer));
よくある間違い
yield*を忘れる:Effect.gen内でyield*を使わずにエフェクトを呼び出すと、その値ではなくエフェクト自体が返されます。- 手動での try/catch:エラーを型チャネル内に保つため、標準の
try/catchの代わりにEffect.tryまたはEffect.catchTagを使用します。
必須のサブスキル:
- 高度なエラー処理には
effect-ts-errors。 - 安全なリソース管理には
effect-ts-resources。
コメント
Markdown 対応