关于 effect-ts-fundamentals
面向复杂 TypeScript 应用开发者的 Effect-TS 基础技能指南,涵盖类型化副作用、依赖注入和异步操作组合。
主要功能
- 01基于生成器的副作用组合
- 02类型安全的服务定义
- 03基于 Layer 的依赖注入
- 04声明式异步流程
适用场景
- 01构建复杂 TypeScript 应用
- 02组合有依赖关系的异步操作
- 03分离服务接口与实现
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ mrevanzak/ effect-ts-skills --skill effect-ts-fundamentals安装后在 Claude Code 中输入/effect-ts-fundamentals确认已加载。
详细介绍
Effect-TS 基础知识
概述
Effect-TS 将副作用视为值,提供了一套统一的工具包,用于构建稳健的应用程序。它支持类型安全的错误处理、依赖注入和资源管理。
适用场景
- 构建需要严格追踪错误的复杂 TypeScript 应用程序时。
- 需要通过依赖注入将实现与接口解耦时。
- 管理必须安全组合的多个异步操作时。
不适用场景:
- 使用标准
Promise和try/catch就足够的简单脚本。 - 团队学习 Effect 的额外负担大于其架构收益的项目。
核心模式
Effect 以声明式、基于生成器的流程取代手动传递依赖和嵌套的 try/catch。
之前(纯 TS):
async function getUserData(userId: string, db: Database) {
try {
const user = await db.findUser(userId);
const posts = await fetchPosts(user.id);
return { user, posts };
} catch (e) {
throw new Error("Failed");
}
}
之后(Effect):
const getUserData = (userId: string) =>
Effect.gen(function* () {
const db = yield* DatabaseService;
const user = yield* db.findUser(userId);
const posts = yield* fetchPosts(user.id);
return { user, posts };
});
快速参考
| 功能 | 工具 | 用途 |
|---|---|---|
| 顺序逻辑 | Effect.gen | 可读的异步流水线 |
| 服务定义 | Effect.Service | 类型安全的 DI 容器 |
| Layer 组合 | Layer.merge/provide | 接线依赖 |
实现
1. 现代服务模式
使用内置访问器定义服务,实现无缝依赖注入。
export class UserService extends Effect.Service<UserService>()("UserService", {
accessors: true,
effect: Effect.gen(function* () {
const db = yield* DatabaseService;
return {
getUser: (id: string) => db.query(`SELECT * FROM users WHERE id = ${id}`)
};
}),
dependencies: [DatabaseService.Default]
}) {}
2. 使用生成器处理顺序逻辑
使用 Effect.gen 和 yield* 组合 Effect,无需回调地狱或手动串联 promise。
const getUserData = (userId: number) =>
Effect.gen(function* () {
const user = yield* fetchUser(userId);
const posts = yield* fetchUserPosts(user.id);
return { user, posts };
});
3. 基于 Layer 的依赖注入
组合实现层,并将它们提供给程序。
const MainLayer = Layer.merge(DatabaseService.Default, LoggerService.Default);
const program = pipe(myEffect, Effect.provide(MainLayer));
常见错误
- 忘记
yield*:在Effect.gen中调用 Effect 时,如果没有使用yield*,返回的是 Effect 本身,而不是它的值。 - 手动使用 try/catch:使用
Effect.try或Effect.catchTag,而不是标准的try/catch,以便让错误保留在类型通道中。
必需的子技能:
- 高级错误处理请使用
effect-ts-errors。 - 安全资源管理请使用
effect-ts-resources。
评论
支持 Markdown