You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何约束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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 07:00:59