mcpField
E
effect-ts

effect-ts

github.com/tenequm开发4062 次安装2 周前更新
代码仓库

关于 effect-ts

面向使用 Effect-TS 的 TypeScript 开发者的编码指导技能,帮助按项目版本编写代码并核对 API。内容覆盖错误处理、依赖注入、并发、资源管理及其他常见开发主题。

主要功能

  1. 01识别 Effect v3 与 v4
  2. 02提供错误处理与类型建模指导
  3. 03指导服务与依赖注入
  4. 04涵盖并发和资源生命周期
  5. 05核对 API 并纠正常见误用

适用场景

  1. 01在现有项目版本中编写 Effect 代码
  2. 02为新项目选择适用的 v4 写法
  3. 03排查错误 API 或版本混用
  4. 04实现并发、重试或资源管理逻辑

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tenequm/skills --skill effect-ts

安装后在 Claude Code 中输入/effect-ts确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

CHANGELOG.md
LICENSE.txt
evals/
evals.json
references/
cli.md
concurrency.md
configuration.md
core-patterns.md
datetime.md
dependency-injection.md
distributed.md
effect-ai.md
error-modeling.md
graph.md
http.md
llm-corrections.md
migration-async.md
migration-v4.md
observability.md
optics.md
resource-management.md
retry-scheduling.md
rpc.md
schema.md
sql.md
stm.md
streams.md
testing.md

详细介绍

Effect-TS

Effect 是一个 TypeScript 库,用于构建可用于生产环境的软件,提供类型化错误、结构化并发、依赖注入和内置可观测性。

版本检测

编写 Effect 代码前,先检测用户使用的版本:

# Check installed version
cat package.json | grep '"effect"'
  • v4.x(推荐,也是 Effect 的发展方向):Context.Service、Effect.catch、Effect.forkChild、Schema.TaggedErrorClass
  • v3.x(稳定版,目前仍常用于生产环境):Context.Tag、Effect.catchAll、Effect.fork、Data.TaggedError

注意:v4 beta 曾短暂使用 ServiceMap 模块,后于 2026-04-07(PR #1961)改回 Context。如果在任何文档或较早的 beta 代码中看到 ServiceMap.*,它现在对应的是 Context.*。v3 和 v4 都从 "effect" 导入 Context;其中的导出有所不同(v4 中为 Context.Service,v3 中为 Context.Tag)。

新项目优先使用 v4——这是 Effect 的发展方向。在现有代码库中,应与已安装的版本保持一致:除非用户提出要求,否则不要将 v3 代码改写为 v4 语法。如果确实无法确定版本,则默认使用 v4,并说明这一点。v4 仍处于 beta 阶段,因此请锁定确切版本(4.0.0-beta.x),并预期 API 偶尔会有变动。

主要文档来源

v4(主要):

v3(适用于现有代码库):

两个版本均适用:

AI 防护措施:关键纠正

大模型经常会生成错误的 Effect API。使用前,请对照参考文档核实每个 API。

常见幻觉(两个版本均适用):

错误(AI 经常生成)正确写法
Effect.cachedWithTTL(...)Cache.make({ capacity, timeToLive, lookup })
Effect.cachedInvalidateWithTTL(...)cache.invalidate(key) / cache.invalidateAll()
Effect.mapError(effect, fn)在管道中使用 Effect.mapError(fn),或使用 Effect.catchTag
import { Schema } from "@effect/schema"import { Schema } from "effect"(v3.10+ 和所有 v4 版本)
import { JSONSchema } from "@effect/schema"import { JSONSchema } from "effect"(v3.10+)
JSON Schema Draft 2020-12Effect Schema 生成的是 Draft-07
“线程局部存储”通过 v3 的 FiberRef / v4 的 Context.Reference 实现“纤程局部存储”
纤程被“取消”纤程被“中断”
所有队列都有背压只有有界队列才有;滑动队列和丢弃队列没有
new MyError("message")new MyError({ message: "..." })(Schema 错误接受对象)

v3 特有的幻觉:

错误正确写法(v3)
Effect.Service(函数调用)class Foo extends Effect.Service<Foo>()("id", {})
Effect.match(effect, { ... })Effect.match(effect, { onSuccess, onFailure })
Effect.provide(layer1, layer2)Effect.provide(Layer.merge(layer1, layer2))

v4 特有的幻觉(AI 可能会混淆 v3 和 v4):

错误(在 v4 代码中使用 v3 API)正确(v4)
Context.Tag("X")(v3 形式)Context.Service<X>(id) 或类语法
ServiceMap.Service / ServiceMap.Reference2026-04-07 更名回 Context.Service / Context.Reference
Effect.catchAll(fn)Effect.catch(fn)
Effect.fork(effect)Effect.forkChild(effect)
Effect.forkDaemon(effect)Effect.forkDetach(effect)
Data.TaggedErrorSchema.TaggedErrorClass
FiberRef.get(ref)yield* References.X(一个 Context.Reference)
yield* ref(将 Ref 作为 Effect)yield* Ref.get(ref)(Ref 不再是 Effect)
yield* fiber(将 Fiber 作为 Effect)yield* Fiber.join(fiber)(Fiber 不再是 Effect)
Logger.Default / Logger.LiveLogger.layer(v4 命名约定)
Schema.TaggedErrorSchema.TaggedErrorClass
Schema.makeUnsafe(input)Schema.make(input)(会抛出 SchemaError);还有实例方法 schema.makeOption(...)、schema.makeEffect(...)
ParseResult(来自 "effect")SchemaIssue 模块 + SchemaError 类;使用 Schema.isSchemaError 进行类型收窄
HttpApiEndpoint.get(n, p).pipe(HttpApiEndpoint.setPath(...), setPayload(...), setSuccess(...))HttpApiEndpoint.get(n, p, { params, query, payload, success, error })(对象选项形式)
Otlp.layer({ url, serviceName })OtlpTracer.layer({ url, resource: { serviceName } }) + OtlpSerialization.layerJson + FetchHttpClient.layer
import { HttpApi } from "@effect/platform"(v4)import { HttpApi } from "effect/unstable/httpapi"
HttpApi 端点的 Schema 错误默认是类型化错误在当前 v4 测试版中,除非经过转换,否则默认是缺陷

请阅读 references/llm-corrections.md,查看完整的修正表。

渐进式披露

只阅读与你的任务相关的参考文件:

  • 错误建模或类型化失败 → references/error-modeling.md
  • 服务、DI 或 Layer 接线 → references/dependency-injection.md
  • 按键动态 Layer(按租户划分的资源、LayerMap)→ references/dependency-injection.md
  • 将 Effect 接入非 Effect 框架(Hono/Express、ManagedRuntime)→ references/dependency-injection.md
  • 重试、超时或退避 → references/retry-scheduling.md
  • Fiber、分叉或并行工作 → references/concurrency.md
  • 请求批处理、消除 N+1、DataLoader 模式 → references/concurrency.md
  • 多提供方回退(ExecutionPlan)→ references/effect-ai.md / references/retry-scheduling.md
  • 流、队列或 SSE → references/streams.md
  • 流分帧(NDJSON / MessagePack 编解码)→ references/streams.md
  • 运行子进程 / 调用 shell → references/concurrency.md
  • 资源生命周期或清理 → references/resource-management.md
  • 可刷新值(轮换凭据、轮询配置)→ references/resource-management.md
  • 引用计数的共享资源(RcRef/RcMap)→ references/resource-management.md
  • Schema 验证或解码 → references/schema.md
  • 品牌类型 / 名义类型(Brand)→ references/schema.md
  • 日志、指标或追踪 → references/observability.md
  • HTTP 客户端或 API 调用 → references/http.md
  • HTTP API 服务端 → references/http.md(涵盖客户端和服务端)
  • 文件上传 / multipart 表单数据 → references/http.md
  • LLM/AI 集成 → references/effect-ai.md
  • 配置、环境变量、密钥 → references/configuration.md
  • SQL / 数据库访问 → references/sql.md
  • 命令行应用 → references/cli.md
  • 类型化客户端/服务端 RPC → references/rpc.md
  • 分片实体、持久化工作流、事件溯源 → references/distributed.md
  • 事务状态(STM、Tx*)→ references/stm.md
  • 日期/时间处理 → references/datetime.md
  • 不可变嵌套更新(optics)→ references/optics.md
  • 图、依赖排序、最短路径、环检测 → references/graph.md
  • 模式匹配(Match)→ references/core-patterns.md
  • 资源池化(Pool)→ references/resource-management.md
  • Fiber 集合、SubscriptionRef、工作线程 → references/concurrency.md
  • 测试 Effect 代码 → references/testing.md
  • 基于属性的测试 / 根据 Schema 生成数据 → references/testing.md
  • 从 async/await 迁移 → references/migration-async.md
  • 从 v3 迁移到 v4 → references/migration-v4.md
  • 核心类型、gen、pipe、运行 → references/core-patterns.md
  • 完整的错误用法与正确用法 API 表 → references/llm-corrections.md

核心工作流

  1. 检测版本:编写任何代码之前,先检查 package.json
  2. 明确边界:确定 IO 发生的位置,并将核心逻辑保留为 Effect 值
  3. 选择风格:顺序逻辑使用 Effect.gen,简单转换使用管道。在 v4 中,命名函数优先使用 Effect.fn("name")
  4. 显式建模错误:在 E 通道中为预期错误标注类型;将 Bug 视为缺陷
  5. 建模依赖:使用服务和层;接口中不要包含构造逻辑
  6. 管理资源:打开/关闭文件、连接等资源时使用 Scope
  7. 提供层,并仅在程序边界处运行 Effect(NodeRuntime.runMain 或 ManagedRuntime)
  8. 使用前确认 API 存在——查阅 https://tim-smart.github.io/effect-io-ai/ 或源文档

入门函数集

从这约 20 个函数开始(官方推荐集):

创建 Effect: Effect.succeed、Effect.fail、Effect.sync、Effect.tryPromise

组合: Effect.gen(v4 中还包括 Effect.fn)、Effect.andThen、Effect.map、Effect.tap、Effect.all

运行: Effect.runPromise、NodeRuntime.runMain(入口点首选)

错误处理: Effect.catchTag、Effect.catch(v4)/ Effect.catchAll(v3)、Effect.orDie

资源: Effect.acquireRelease、Effect.acquireUseRelease、Effect.scoped

依赖项: Effect.provide、Effect.provideService

关键模块: Effect、Schema、Layer、Option、Result(v4)/ Either(v3)、Array、Match

DI(v4): Context.Service、Context.Reference、Layer.effect、Effect.fn("name") DI(v3): Context.Tag、Context.Reference

导入模式

始终从 "effect" 使用聚合导入:

import { Context, Effect, Schema, Layer, Option, Stream } from "effect"

对于配套软件包,从软件包名称导入。v3 和 v4 在此处有所不同:

// v4 (recommended) - platform transports still separate, but HttpApi / observability
// moved under effect/unstable/*
import { NodeRuntime } from "@effect/platform-node"
import { FetchHttpClient } from "effect/unstable/http"
import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiBuilder, HttpApiScalar } from "effect/unstable/httpapi"
import { OtlpLogger, OtlpSerialization, OtlpTracer } from "effect/unstable/observability"

// v3 (stable) companion packages
import { NodeRuntime } from "@effect/platform-node"
import { HttpClient } from "@effect/platform"
import { NodeSdk } from "@effect/opentelemetry"

除非打包工具需要通过深层模块导入(effect/Effect)来进行 tree-shaking,否则应避免这样做。

输出规范

  • 在每个代码示例中展示导入语句
  • 多步骤逻辑优先使用 Effect.gen(命令式);转换优先使用管道
  • 在 v4 中,命名函数使用 Effect.fn("name"),而不是裸用 Effect.gen;内部辅助函数若不需要 span/stack-frame,则使用 Effect.fnUntraced
  • 库代码中绝不调用 Effect.runPromise / Effect.runSync——仅在程序边界处调用
  • CLI/服务入口点使用 NodeRuntime.runMain(可优雅处理 SIGINT)
  • 将 Effect 集成到非 Effect 框架(Hono、Express 等)时,使用 ManagedRuntime
  • 在生成器中引发错误时,始终使用 return yield*(确保 TS 理解控制流)
  • 避免 point-free/tacit 用法:写成 Effect.map((x) => fn(x),而不是 Effect.map(fn)(泛型会被擦除)
  • 明确保持依赖关系图(服务、层、标签)
  • 有助于设计决策时,说明 Effect<A, E, R> 的形状

Agent 质量检查清单

输出 Effect 代码前,请核对:

  • 每个 API 均存在(对照 tim-smart API 列表或源文档检查)
  • 导入来自 "effect"(而非 @effect/schema、@effect/io 等)
  • 版本与用户的代码库一致(v3 与 v4 语法)
  • 预期错误已在 E 中进行类型标注;意外失败属于缺陷
  • 仅在程序边界处调用 run*,而非在库代码中调用
  • 使用 acquireRelease 打开的资源均包装在 Effect.scoped 中
  • 运行前已提供层(没有缺失的 R 要求)
  • 生成器主体使用 yield*(而非不带 * 的 yield)
  • 在生成器中引发错误时使用 return yield* 模式

评论

支持 Markdown