effect-ts
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEffect TypeScript Best Practices
Effect TypeScript最佳实践
Effect is a TypeScript library for building complex, type-safe applications with structured
error handling, dependency injection via services/layers, fiber-based concurrency, and
resource safety.
Effect是一个TypeScript库,用于构建具备结构化错误处理、基于服务/层的依赖注入、纤程级并发以及资源安全性的复杂类型安全应用。
When to Apply
适用场景
- Writing or reviewing TypeScript code that imports from ,
effect, or@effect/schema@effect/platform - Implementing typed error handling with
Effect<Success, Error, Requirements> - Building services and layers for dependency injection
- Working with Schema for data validation, decoding, and transformation
- Using fiber-based concurrency (queues, semaphores, PubSub, deferred)
- Processing data with Stream and Sink
- Migrating from Promises, fp-ts, neverthrow, or ZIO to Effect
- 编写或审查从、
effect或@effect/schema导入的TypeScript代码@effect/platform - 使用实现类型化错误处理
Effect<Success, Error, Requirements> - 构建用于依赖注入的服务与层
- 使用Schema进行数据验证、解码与转换
- 使用基于纤程的并发机制(队列、信号量、PubSub、Deferred)
- 通过Stream和Sink处理数据
- 从Promises、fp-ts、neverthrow或ZIO迁移至Effect
How to Use
使用方法
This skill is organized by domain. Read the relevant reference file for the area you're working in.
本技能按领域划分,阅读与你当前工作领域相关的参考文档即可。
Read First: The Paradigm
必读:范式转变
Always read this before diving into API references, especially when refactoring existing
code to use Effect or writing new Effect services:
| Reference | When to Read |
|---|---|
| Think in Effect: The Paradigm Shift | Before any other reference. Mental model shifts, refactoring recipes, anti-patterns, application architecture. Read this to understand HOW to think in Effect — the other files teach WHAT to type. |
在深入API参考之前,请务必阅读本文档,尤其是在重构现有代码以使用Effect或编写新的Effect服务时:
| 参考文档 | 阅读时机 |
|---|---|
| Effect思维:范式转变 | 优先于其他所有参考文档。思维模型转变、重构方案、反模式、应用架构。阅读本文以理解如何用Effect的思维思考——其他文档会教你具体的代码写法。 |
Core Foundations
核心基础
| Reference | When to Read |
|---|---|
| Getting Started | Creating the Effect type, pipelines, generators, running effects |
| Error Management | Typed errors, recovery, retrying, timeouts, sandboxing |
| Core Concepts | Request batching, configuration management, runtime system |
| 参考文档 | 阅读时机 |
|---|---|
| 入门指南 | 创建Effect类型、管道、生成器、运行Effect |
| 错误管理 | 类型化错误、恢复机制、重试、超时、沙箱隔离 |
| 核心概念 | 请求批处理、配置管理、运行时系统 |
Data & Validation
数据与验证
| Reference | When to Read |
|---|---|
| Data Types | Option, Either, Cause, Chunk, DateTime, Duration, Exit, Data |
| Schema Basics | Schema intro, basic usage, classes, constructors, effect data types |
| Schema Advanced | Transformations, filters, annotations, error formatting, JSON Schema output |
| 参考文档 | 阅读时机 |
|---|---|
| 数据类型 | Option、Either、Cause、Chunk、DateTime、Duration、Exit、Data |
| Schema基础 | Schema介绍、基础用法、类、构造函数、Effect数据类型 |
| Schema进阶 | 转换、过滤、注解、错误格式化、JSON Schema输出 |
Architecture & Dependencies
架构与依赖
| Reference | When to Read |
|---|---|
| Requirements Management | Services, Layers, dependency injection, layer memoization |
| Resource Management | Scope, safe resource acquisition/release, caching |
| State Management | Ref, SubscriptionRef, SynchronizedRef for concurrent state |
| 参考文档 | 阅读时机 |
|---|---|
| 需求管理 | 服务、Layer、依赖注入、Layer缓存 |
| 资源管理 | Scope、安全的资源获取/释放、缓存 |
| 状态管理 | Ref、SubscriptionRef、SynchronizedRef用于并发状态管理 |
Concurrency & Streaming
并发与流处理
| Reference | When to Read |
|---|---|
| Concurrency | Fibers, Deferred, Latch, PubSub, Queue, Semaphore |
| Streams and Sinks | Creating, consuming, transforming streams; sink operations |
| Scheduling | Built-in schedules, cron, combinators, repetition |
| 参考文档 | 阅读时机 |
|---|---|
| 并发 | Fibers、Deferred、Latch、PubSub、Queue、Semaphore |
| 流与接收器 | 创建、消费、转换流;接收器操作 |
| 调度 | 内置调度器、 cron、组合器、重复执行 |
Platform & Observability
平台与可观测性
| Reference | When to Read |
|---|---|
| Platform | FileSystem, Command, Terminal, KeyValueStore, Path |
| Observability | Logging, metrics, tracing, Supervisor |
| Testing | TestClock for time simulation; for service mocking and layer testing, see Requirements Management |
| 参考文档 | 阅读时机 |
|---|---|
| 平台 | FileSystem、Command、Terminal、KeyValueStore、Path |
| 可观测性 | 日志、指标、追踪、Supervisor |
| 测试 | TestClock用于时间模拟;服务模拟与Layer测试请参考需求管理 |
Style, AI & Migration
风格、AI与迁移
| Reference | When to Read |
|---|---|
| Code Style | Branded types, pattern matching, dual APIs, guidelines, traits |
| AI Integration | Effect AI packages for LLM tool use and execution planning |
| Micro | Lightweight Effect alternative for smaller bundles |
| Migration Guides | Coming from Promises, fp-ts, neverthrow, or ZIO |
| 参考文档 | 阅读时机 |
|---|---|
| 代码风格 | 品牌类型、模式匹配、双API、指南、特性 |
| AI集成 | 用于LLM工具调用与执行规划的Effect AI包 |
| Micro | 轻量级Effect替代方案,适用于更小的包体积 |
| 迁移指南 | 从Promises、fp-ts、neverthrow或ZIO迁移 |
Quick Reference — Common Patterns
快速参考——常见模式
The Effect Type
Effect类型
ts
// ┌─── Success type
// │ ┌─── Error type
// │ │ ┌─── Required dependencies
// ▼ ▼ ▼
Effect<Success, Error, Requirements>ts
// ┌─── 成功类型
// │ ┌─── 错误类型
// │ │ ┌─── 所需依赖
// ▼ ▼ ▼
Effect<Success, Error, Requirements>Creating Effects
创建Effect
ts
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 }
})ts
import { Effect } from "effect"
// 从同步值创建
const succeed = Effect.succeed(42)
const fail = Effect.fail(new Error("oops"))
// 从可能抛出异常的同步代码创建
const sync = Effect.try(() => JSON.parse(data))
// 从Promise创建
const async = Effect.tryPromise(() => fetch(url))
// 从生成器创建(推荐用于复杂流程)
const program = Effect.gen(function* () {
const user = yield* getUser(id)
const todos = yield* getTodos(user.id)
return { user, todos }
})Running Effects
运行Effect
ts
// Async (returns Promise)
Effect.runPromise(program)
// With full Exit information
Effect.runPromiseExit(program)
// Sync (throws on async)
Effect.runSync(program)ts
// 异步(返回Promise)
Effect.runPromise(program)
// 获取完整Exit信息
Effect.runPromiseExit(program)
// 同步(异步代码会抛出异常)
Effect.runSync(program)Typed Errors
类型化错误
ts
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* () {
// ...
})ts
import { Data, Effect } from "effect"
class NotFound extends Data.TaggedError("NotFound")<{
readonly id: string
}> {}
class Unauthorized extends Data.TaggedError("Unauthorized")<{}> {}
// 错误类型被追踪:Effect<User, NotFound | Unauthorized>
const getUser = (id: string) =>
Effect.gen(function* () {
// ...
})Services and Layers
服务与Layer
ts
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)ts
import { Context, Effect, Layer } from "effect"
// 定义服务
class UserRepo extends Context.Tag("UserRepo")<
UserRepo,
{ readonly findById: (id: string) => Effect.Effect<User, NotFound> }
>() {}
// 在Effect中使用——添加到依赖通道
const program = Effect.gen(function* () {
const repo = yield* UserRepo
return yield* repo.findById("1")
})
// 用Layer实现
const UserRepoLive = Layer.succeed(UserRepo, {
findById: (id) => Effect.succeed({ id, name: "Alice" })
})
// 提供依赖并运行
program.pipe(Effect.provide(UserRepoLive), Effect.runPromise)Schema Validation
Schema验证
ts
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: "a@b.com" })ts
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
// 解码(解析+验证)
const decode = Schema.decodeUnknownSync(User)
const user = decode({ id: 1, name: "Alice", email: "a@b.com" })Pipelines
管道
ts
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))
)ts
import { Effect, pipe } from "effect"
// 数据后置(管道风格)
const result = pipe(
getTodos,
Effect.map((todos) => todos.filter((t) => !t.done)),
Effect.flatMap((active) => sendNotification(active.length)),
Effect.catchTag("NetworkError", () => Effect.succeed("offline"))
)
// 链式调用(方法风格)
const result2 = getTodos.pipe(
Effect.map((todos) => todos.filter((t) => !t.done)),
Effect.flatMap((active) => sendNotification(active.length))
)Gotchas
注意事项
See gotchas.md for known failure points.
请查看gotchas.md了解已知的失败点。