diff --git a/.changeset/tasty-seals-film.md b/.changeset/tasty-seals-film.md new file mode 100644 index 00000000000..c77b4fc1575 --- /dev/null +++ b/.changeset/tasty-seals-film.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +fix Effect.Tag generated proxy functions to work with andThen/tap, or others that do function/isEffect checks diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index efeafe69b44..4628061e770 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -5336,8 +5336,18 @@ export const Tag: (id: Id) => () => if (cache.has(prop)) { return cache.get(prop) } - // @ts-expect-error - const fn = (...args: Array) => core.andThen(TagClass, (s: any) => s[prop](...args)) + const fn = (...args: Array) => + // @ts-expect-error + core.andThen(TagClass, (s: any) => { + if (typeof s[prop] === "function") { + // @ts-expect-error + cache.set(prop, (...args: Array) => core.andThen(TagClass, (s: any) => s[prop](...args))) + return s[prop](...args) + } + // @ts-expect-error + cache.set(prop, core.andThen(TagClass, (s) => s[prop])) + return s[prop] + }) // @ts-expect-error const cn = core.andThen(TagClass, (s) => s[prop]) Object.assign(fn, cn) diff --git a/packages/effect/test/Effect/environment.test.ts b/packages/effect/test/Effect/environment.test.ts index 8f4635d7bbd..94d760bf6cc 100644 --- a/packages/effect/test/Effect/environment.test.ts +++ b/packages/effect/test/Effect/environment.test.ts @@ -45,6 +45,24 @@ class NumberTag extends Effect.Tag("NumberTag")() { } describe("Effect", () => { + describe("and Then", () => { + it.effect("effect tag", () => + Effect.gen(function*($) { + const [n, s, z] = yield* $(Effect.all([ + Effect.andThen(Effect.unit, DemoTag.getNumbers), + Effect.andThen(Effect.succeed("a"), DemoTag.strings), + Effect.andThen(Effect.succeed("a"), DemoTag.fn) + ])) + expect(n).toEqual([0, 1]) + expect(s).toEqual(["a", "b"]) + expect(z).toEqual(["a"]) + }).pipe(Effect.provideService(DemoTag, { + getNumbers: () => [0, 1], + strings: ["a", "b"], + fn: (...args) => Array.from(args), + fnGen: (s) => [s] + }))) + }) it.effect("effect tag", () => Effect.gen(function*($) { const [n, s, z] = yield* $(Effect.all([