effect-ts

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Effect TS

Effect TS

Write idiomatic Effect code instead of promise-shaped TypeScript with Effect wrappers pasted on top.
编写符合风格的Effect代码,而不是在Promise风格的TypeScript上粘贴Effect包装器。

Start

开始

  1. Inspect the repo first:
    package.json
    ,
    tsconfig*
    , lockfile, existing
    effect
    /
    @effect/*
    imports, and nearby tests.
  2. Match the task to the smallest useful reference set below.
  3. If
    effect-solutions
    is installed, run
    effect-solutions list
    and
    effect-solutions show <topic>...
    before freehanding a pattern.
  4. Follow local repo conventions before importing a new Effect pattern.
  1. 先检查仓库:
    package.json
    tsconfig*
    、锁文件、已有的
    effect
    /
    @effect/*
    导入,以及相关测试。
  2. 将任务与下方最小实用参考集匹配。
  3. 如果已安装
    effect-solutions
    ,在手动编写模式前先运行
    effect-solutions list
    effect-solutions show <topic>...
  4. 在引入新的Effect模式前,遵循本地仓库的约定。

Read By Task

按任务查阅

  • Setup, install, tsconfig, or repo audit → references/setup-tooling.md
  • Core application code → references/core-patterns.md
  • HTTP, CLI, platform, or stream work → references/ecosystem-patterns.md
  • Promise interop, framework boundaries, runtime issues, or gradual migration → references/adoption-runtime.md
  • 安装、配置、tsconfig或仓库审计 → references/setup-tooling.md
  • 核心应用代码 → references/core-patterns.md
  • HTTP、CLI、平台或流处理工作 → references/ecosystem-patterns.md
  • Promise互操作、框架边界、运行时问题或渐进式迁移 → references/adoption-runtime.md

Topic Map

主题映射

  • effect-solutions show project-setup tsconfig
    for bootstrap work.
  • effect-solutions show basics services-and-layers data-modeling error-handling config testing
    for core application code.
  • effect-solutions show http-clients cli use-pattern
    for ecosystem and integration work.
  • Use
    effect.website/docs
    for deeper API detail, exhaustive module surfaces, and topics not yet covered here.
  • 启动工作使用
    effect-solutions show project-setup tsconfig
  • 核心应用代码使用
    effect-solutions show basics services-and-layers data-modeling error-handling config testing
  • 生态系统和集成工作使用
    effect-solutions show http-clients cli use-pattern
  • 如需更深入的API细节、完整的模块内容以及此处未涵盖的主题,请访问
    effect.website/docs

Defaults

默认规范

  • Use
    Effect.gen
    for inline programs and
    Effect.fn("Name")
    for reusable named effectful functions.
  • Keep
    Effect.run*
    at app edges, tests, workers, or framework adapters.
  • Put dependencies in services and layers, not hidden globals.
  • Parse external data once at the boundary with
    Schema
    , then pass typed values inward.
  • Model recoverable failures with tagged errors and narrow unions.
  • Prefer test layers and
    @effect/vitest
    over ad hoc mocks.
ts
const loadUser = Effect.fn("loadUser")(function* (id: UserId) {
  const repo = yield* UserRepo
  return yield* repo.get(id)
})

const program = Effect.gen(function* () {
  const input = yield* Schema.decodeUnknown(UserInput)(payload)
  return yield* loadUser(input.id)
})
  • 内联程序使用
    Effect.gen
    ,可复用的命名有副作用函数使用
    Effect.fn("Name")
  • Effect.run*
    放在应用边缘、测试、工作线程或框架适配器中。
  • 将依赖项放在服务和层中,而不是隐藏的全局变量里。
  • 在边界处使用
    Schema
    解析外部数据一次,然后向内传递类型化的值。
  • 使用标记错误和窄联合对可恢复故障建模。
  • 优先使用测试层和
    @effect/vitest
    而非临时模拟。
ts
const loadUser = Effect.fn("loadUser")(function* (id: UserId) {
  const repo = yield* UserRepo
  return yield* repo.get(id)
})

const program = Effect.gen(function* () {
  const input = yield* Schema.decodeUnknown(UserInput)(payload)
  return yield* loadUser(input.id)
})

Source Order

参考优先级

  1. Use local project code and tests as the primary contract.
  2. Use
    effect-solutions
    for opinionated patterns and tradeoffs.
  3. Use
    effect.website
    for the canonical API surface.
  4. If a local clone of the Effect repo exists, grep it for real implementations before guessing.
ts
class UserRepo extends Context.Tag("UserRepo")<
  UserRepo,
  { readonly get: (id: UserId) => Effect.Effect<User, UserNotFound> }
>() {}

const UserRepoLive = Layer.succeed(UserRepo, {
  get: (id) => Effect.gen(function* () {
    const sql = yield* SqlClient.SqlClient
    const rows = yield* sql`SELECT * FROM users WHERE id = ${id}`
    if (rows.length === 0) return yield* new UserNotFound({ id })
    return rows[0] as User
  }),
})
  1. 将本地项目代码和测试作为主要依据。
  2. 使用
    effect-solutions
    获取有主见的模式和权衡方案。
  3. 使用
    effect.website
    获取规范的API内容。
  4. 如果存在Effect仓库的本地克隆,在猜测前先搜索其中的真实实现。
ts
class UserRepo extends Context.Tag("UserRepo")<
  UserRepo,
  { readonly get: (id: UserId) => Effect.Effect<User, UserNotFound> }
>() {}

const UserRepoLive = Layer.succeed(UserRepo, {
  get: (id) => Effect.gen(function* () {
    const sql = yield* SqlClient.SqlClient
    const rows = yield* sql`SELECT * FROM users WHERE id = ${id}`
    if (rows.length === 0) return yield* new UserNotFound({ id })
    return rows[0] as User
  }),
})

Avoid

避坑指南

  • Returning raw
    Promise
    values from service methods unless the boundary forces it.
  • Calling
    Effect.runPromise
    deep inside domain code.
  • Using string errors when a tagged error should exist.
  • Re-validating already parsed domain data in the core.
  • Reaching for advanced abstractions before the simpler service / layer / schema model fits.
  • 除非边界强制要求,否则不要从服务方法返回原始
    Promise
    值。
  • 不要在领域代码深处调用
    Effect.runPromise
  • 当应该使用标记错误时,不要使用字符串错误。
  • 不要在核心部分重新验证已解析的领域数据。
  • 不要在更简单的服务/层/模式模型适用前就使用高级抽象。