effect-ts について
Effect を使う TypeScript の作成やレビュー向けのリファレンススキルです。基礎概念、エラー処理、並行処理、プラットフォーム API、移行を分野別にまとめています。
主な機能
- 01分野別の Effect リファレンス
- 02型付きエラーと回復パターン
- 03サービス、レイヤー、リソース安全性
- 04Schema による検証と変換
- 05並行処理、ストリーム、スケジューリング
- 06関連ライブラリからの移行ガイド
活用シーン
- 01Effect を使うコードのレビュー
- 02依存性注入を用いたサービス設計
- 03Schema によるデータ検証と変換
- 04Promise ベースのコードから Effect への移行
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill effect-tsインストール後、Claude Code で/effect-tsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
gotchas.mdmetadata.jsonreferences/_sections.mdai-integration.mdcode-style.mdconc-concurrency.mdcore-concepts.mddata-types.mderror-management.mdgetting-paradigm.mdgetting-started.mdmicro-module.mdmigration-guides.mdobs-observability.mdplat-platform.mdreq-management.mdresource-management.mdsched-scheduling.mdschema-advanced.mdschema-basics.mdstate-management.mdstreams-and-sinks.mdtest-testing.md詳細
Effect TypeScript のベストプラクティス
Effect は、構造化されたエラーハンドリング、サービス/レイヤーによる依存性注入、ファイバーベースの並行処理、リソースの安全性を備えた、複雑で型安全なアプリケーションを構築するための TypeScript ライブラリです。
適用する場面
effect、@effect/schema、@effect/platformからインポートする TypeScript コードを記述またはレビューする場合Effect<Success, Error, Requirements>を使った型付きエラーハンドリングを実装する場合- 依存性注入のためのサービスとレイヤーを構築する場合
- データの検証、デコード、変換に Schema を使用する場合
- ファイバーベースの並行処理(キュー、セマフォ、PubSub、deferred)を使用する場合
- Stream と Sink でデータを処理する場合
- Promises、fp-ts、neverthrow、ZIO から Effect に移行する場合
使用方法
このスキルはドメイン別に構成されています。作業する分野に応じたリファレンスファイルをお読みください。
まず読む:パラダイム
特に既存のコードを Effect にリファクタリングする場合や、新しい Effect サービスを記述する場合は、API リファレンスを読み進める前に必ずこちらをお読みください。
| リファレンス | 読むタイミング |
|---|---|
| Effect で考える:パラダイムシフト | ほかのリファレンスを読む前にお読みください。 メンタルモデルの転換、リファクタリングのレシピ、アンチパターン、アプリケーションアーキテクチャについて説明します。Effect でどのように考えるべきかを理解するためにお読みください。ほかのファイルでは、何を入力するかを説明します。 |
コアの基礎
| リファレンス | 読むタイミング |
|---|---|
| はじめに | Effect 型の作成、パイプライン、ジェネレーター、エフェクトの実行 |
| エラー管理 | 型付きエラー、リカバリー、リトライ、タイムアウト、サンドボックス化 |
| コアコンセプト | リクエストのバッチ処理、設定管理、ランタイムシステム |
データと検証
| リファレンス | 読むタイミング |
|---|---|
| データ型 | Option、Either、Cause、Chunk、DateTime、Duration、Exit、Data |
| Schema の基本 | Schema の概要、基本的な使い方、クラス、コンストラクター、エフェクトのデータ型 |
| Schema の応用 | 変換、フィルター、アノテーション、エラーのフォーマット、JSON Schema の出力 |
アーキテクチャと依存関係
| リファレンス | 読むタイミング |
|---|---|
| 要件管理 | サービス、レイヤー、依存性注入、レイヤーのメモ化 |
| リソース管理 | Scope、安全なリソースの取得/解放、キャッシュ |
| 状態管理 | 並行状態のための Ref、SubscriptionRef、SynchronizedRef |
並行処理とストリーミング
| リファレンス | 読むタイミング |
|---|---|
| 並行処理 | ファイバー、Deferred、Latch、PubSub、Queue、Semaphore |
| ストリームとシンク | ストリームの作成、消費、変換、シンクの操作 |
| スケジューリング | 組み込みスケジュール、cron、コンビネーター、繰り返し |
プラットフォームと可観測性
| リファレンス | 読むタイミング |
|---|---|
| プラットフォーム | FileSystem、Command、Terminal、KeyValueStore、Path |
| 可観測性 | ロギング、メトリクス、トレーシング、Supervisor |
| テスト | 時間のシミュレーションに使う TestClock。サービスのモック化とレイヤーのテストについては、要件管理を参照してください。 |
スタイル、AI、移行
| リファレンス | 読むタイミング |
|---|---|
| コードスタイル | ブランド型、パターンマッチング、デュアル API、ガイドライン、トレイト |
| AI 統合 | LLM のツール利用と実行計画に対応する Effect AI パッケージ |
| Micro | バンドルを小さくしたい場合に使える軽量な Effect の代替手段 |
| 移行ガイド | Promise、fp-ts、neverthrow、ZIO からの移行 |
クイックリファレンス — よく使うパターン
Effect 型
// ┌─── Success type
// │ ┌─── Error type
// │ │ ┌─── Required dependencies
// ▼ ▼ ▼
Effect<Success, Error, Requirements>
Effect の作成
import { Effect } from "effect"
// From sync values
const succeed = Effect.succeed(42)
const fail = Effect.fail(new Error("oops"))
// From sync code that may throw
const sync = Effect.try(() => JSON.parse(data))
// From promises
const async = Effect.tryPromise(() => fetch(url))
// From generators (recommended for complex flows)
const program = Effect.gen(function* () {
const user = yield* getUser(id)
const todos = yield* getTodos(user.id)
return { user, todos }
})
Effect の実行
// Async (returns Promise)
Effect.runPromise(program)
// With full Exit information
Effect.runPromiseExit(program)
// Sync (throws on async)
Effect.runSync(program)
型付きエラー
import { Data, Effect } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{
readonly id: string
}> {}
class Unauthorized extends Data.TaggedError("Unauthorized")<{}> {}
// Error type is tracked: Effect<User, NotFound | Unauthorized>
const getUser = (id: string) =>
Effect.gen(function* () {
// ...
})
サービスとレイヤー
import { Context, Effect, Layer } from "effect"
// Define a service
class UserRepo extends Context.Tag("UserRepo")<
UserRepo,
{ readonly findById: (id: string) => Effect.Effect<User, NotFound> }
>() {}
// Use in effects — adds to Requirements channel
const program = Effect.gen(function* () {
const repo = yield* UserRepo
return yield* repo.findById("1")
})
// Implement with a Layer
const UserRepoLive = Layer.succeed(UserRepo, {
findById: (id) => Effect.succeed({ id, name: "Alice" })
})
// Provide and run
program.pipe(Effect.provide(UserRepoLive), Effect.runPromise)
スキーマ検証
import { Schema } from "effect"
const User = Schema.Struct({
id: Schema.Number,
name: Schema.String,
email: Schema.String.pipe(Schema.pattern(/@/))
})
type User = typeof User.Type
// Decode (parse + validate)
const decode = Schema.decodeUnknownSync(User)
const user = decode({ id: 1, name: "Alice", email: "[email protected]" })
パイプライン
import { Effect, pipe } from "effect"
// Data-last (pipe style)
const result = pipe(
getTodos,
Effect.map((todos) => todos.filter((t) => !t.done)),
Effect.flatMap((active) => sendNotification(active.length)),
Effect.catchTag("NetworkError", () => Effect.succeed("offline"))
)
// Fluent (method style)
const result2 = getTodos.pipe(
Effect.map((todos) => todos.filter((t) => !t.done)),
Effect.flatMap((active) => sendNotification(active.length))
)
注意点
既知の失敗箇所については、gotchas.md を参照してください。
コメント
Markdown 対応