如何约束Effect的成功类型且不限制错误与上下文?
解决方法
你的问题出在Handler类型的定义上,默认的Effect.Effect<Event<any>[]>等价于Effect.Effect<Event<any>[], never, never>——这意味着它不允许抛出任何错误,也不依赖任何上下文,所以带错误的handler2和带依赖的handler3都无法匹配这个类型。
要实现“仅限定成功类型,放开错误和上下文约束”,只需要显式指定Effect的后两个泛型参数为任意类型即可:
import { Context, Effect } from "effect"; export class ExternalDep extends Context.Tag("ExternalDep")< ExternalDep, { bar: Effect.Effect<{ foo: string }> } >() {} type Event<Payload = void> = { id: string; payload: Payload }; // 修改Handler类型:固定成功类型为Event<any>[], 错误和上下文允许任意类型 export type Handler = (input: { foo: string }) => Effect.Effect<Event<any>[], any, any>; const handler1: Handler = ({ foo }) => Effect.gen(function* () { return [{ id: "test", payload: undefined }]; }); // 现在可以正常工作:错误类型为Error,符合any约束 const handler2: Handler = ({ foo }) => Effect.gen(function* () { yield* Effect.fail(new Error("Test")); return [{ id: "test", payload: { foo: "bar" } }]; }); // 现在可以正常工作:上下文包含ExternalDep,符合any约束 const handler3: Handler = ({ foo }) => Effect.gen(function* () { const dep = yield* ExternalDep; const foo = yield* dep.bar; return [{ id: "test", payload: { foo } }]; });
补充说明
- Effect的泛型签名是
Effect.Effect<A, E, R>,其中:A是成功值类型(你要固定的部分)E是错误类型(这里设为any,允许任意错误)R是上下文依赖类型(这里设为any,允许任意依赖)
- 如果想要更严谨的约束(比如错误必须是
Error子类),可以把any换成Error;如果允许任意错误但不想用any,也可以用unknown,但any是最宽松的选项,能完全满足你的需求。
内容的提问来源于stack exchange,提问作者florian norbert bepunkt
相关产品推荐
相关产品推荐

