effect-ts

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Effect 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
    ,
    @effect/schema
    , or
    @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
    @effect/platform
    导入的TypeScript代码
  • 使用
    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:
ReferenceWhen to Read
Think in Effect: The Paradigm ShiftBefore 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

核心基础

ReferenceWhen to Read
Getting StartedCreating the Effect type, pipelines, generators, running effects
Error ManagementTyped errors, recovery, retrying, timeouts, sandboxing
Core ConceptsRequest batching, configuration management, runtime system
参考文档阅读时机
入门指南创建Effect类型、管道、生成器、运行Effect
错误管理类型化错误、恢复机制、重试、超时、沙箱隔离
核心概念请求批处理、配置管理、运行时系统

Data & Validation

数据与验证

ReferenceWhen to Read
Data TypesOption, Either, Cause, Chunk, DateTime, Duration, Exit, Data
Schema BasicsSchema intro, basic usage, classes, constructors, effect data types
Schema AdvancedTransformations, filters, annotations, error formatting, JSON Schema output
参考文档阅读时机
数据类型Option、Either、Cause、Chunk、DateTime、Duration、Exit、Data
Schema基础Schema介绍、基础用法、类、构造函数、Effect数据类型
Schema进阶转换、过滤、注解、错误格式化、JSON Schema输出

Architecture & Dependencies

架构与依赖

ReferenceWhen to Read
Requirements ManagementServices, Layers, dependency injection, layer memoization
Resource ManagementScope, safe resource acquisition/release, caching
State ManagementRef, SubscriptionRef, SynchronizedRef for concurrent state
参考文档阅读时机
需求管理服务、Layer、依赖注入、Layer缓存
资源管理Scope、安全的资源获取/释放、缓存
状态管理Ref、SubscriptionRef、SynchronizedRef用于并发状态管理

Concurrency & Streaming

并发与流处理

ReferenceWhen to Read
ConcurrencyFibers, Deferred, Latch, PubSub, Queue, Semaphore
Streams and SinksCreating, consuming, transforming streams; sink operations
SchedulingBuilt-in schedules, cron, combinators, repetition
参考文档阅读时机
并发Fibers、Deferred、Latch、PubSub、Queue、Semaphore
流与接收器创建、消费、转换流;接收器操作
调度内置调度器、 cron、组合器、重复执行

Platform & Observability

平台与可观测性

ReferenceWhen to Read
PlatformFileSystem, Command, Terminal, KeyValueStore, Path
ObservabilityLogging, metrics, tracing, Supervisor
TestingTestClock for time simulation; for service mocking and layer testing, see Requirements Management
参考文档阅读时机
平台FileSystem、Command、Terminal、KeyValueStore、Path
可观测性日志、指标、追踪、Supervisor
测试TestClock用于时间模拟;服务模拟与Layer测试请参考需求管理

Style, AI & Migration

风格、AI与迁移

ReferenceWhen to Read
Code StyleBranded types, pattern matching, dual APIs, guidelines, traits
AI IntegrationEffect AI packages for LLM tool use and execution planning
MicroLightweight Effect alternative for smaller bundles
Migration GuidesComing 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了解已知的失败点。