From 29ca32920f6cce0c12b927ea3c4d1957764486b2 Mon Sep 17 00:00:00 2001 From: "maksim.khramtsov" Date: Fri, 25 Oct 2024 13:02:57 +0200 Subject: [PATCH] Support union of parameters in functions in `Effect.Tag.Proxy` type --- .changeset/four-items-itch.md | 5 +++++ packages/effect/src/Effect.ts | 13 +++++++++---- packages/effect/test/Effect/environment.test.ts | 15 +++++++++++---- 3 files changed, 25 insertions(+), 8 deletions(-) create mode 100644 .changeset/four-items-itch.md diff --git a/.changeset/four-items-itch.md b/.changeset/four-items-itch.md new file mode 100644 index 0000000000..6b2b1c190b --- /dev/null +++ b/.changeset/four-items-itch.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +Support union of parameters in functions in `Effect.Tag.Proxy` type diff --git a/packages/effect/src/Effect.ts b/packages/effect/src/Effect.ts index 14e3e17824..443b7a5e4f 100644 --- a/packages/effect/src/Effect.ts +++ b/packages/effect/src/Effect.ts @@ -6497,14 +6497,19 @@ export declare namespace Tag { */ export type Proxy = { [ - k in keyof Type as Type[k] extends ((...args: [...infer Args]) => infer Ret) ? + k in keyof Type as Type[k] extends ((...args: infer Args extends ReadonlyArray) => infer Ret) ? ((...args: Readonly) => Ret) extends Type[k] ? k : never : k - ]: Type[k] extends (...args: [...infer Args]) => Effect ? + ]: Type[k] extends (...args: infer Args extends ReadonlyArray) => Effect ? (...args: Readonly) => Effect - : Type[k] extends (...args: [...infer Args]) => infer A ? (...args: Readonly) => Effect + : Type[k] extends (...args: infer Args extends ReadonlyArray) => infer A ? + (...args: Readonly) => Effect : Type[k] extends Effect ? Effect - : Effect + : Effect< + Type[k] extends (...args: infer Args extends ReadonlyArray) => any ? [Type[k], Args] : [Type[k], "no"], + never, + Self + > } } diff --git a/packages/effect/test/Effect/environment.test.ts b/packages/effect/test/Effect/environment.test.ts index 03ec8bab68..67b2941c19 100644 --- a/packages/effect/test/Effect/environment.test.ts +++ b/packages/effect/test/Effect/environment.test.ts @@ -27,6 +27,9 @@ class DemoTag extends Effect.Tag("DemoTag") Array readonly strings: Array readonly fn: (...args: ReadonlyArray) => Array + readonly fnParamsUnion: ( + ...args: ReadonlyArray | [number] | [false, true] + ) => ReadonlyArray | [number] | [false, true] readonly fnGen: (s: S) => Array }>() { } @@ -69,28 +72,32 @@ describe("Effect", () => { getNumbers: () => [0, 1], strings: ["a", "b"], fn: (...args) => Array.from(args), - fnGen: (s) => [s] + fnGen: (s) => [s], + fnParamsUnion: (..._args) => _args }))) }) it.effect("effect tag", () => Effect.gen(function*($) { - const [n, s, z] = yield* $(Effect.all([ + const [n, s, z, zUnion] = yield* $(Effect.all([ DemoTag.getNumbers(), DemoTag.strings, - DemoTag.fn("a", "b", "c") + DemoTag.fn("a", "b", "c"), + DemoTag.fnParamsUnion(1) ])) const s2 = yield* $(DemoTag.pipe(Effect.map((_) => _.strings))) const s3 = yield* $(DemoTag.use((_) => _.fnGen("hello"))) expect(n).toEqual([0, 1]) expect(s).toEqual(["a", "b"]) expect(z).toEqual(["a", "b", "c"]) + expect(zUnion).toEqual([1]) expect(s2).toEqual(["a", "b"]) expect(s3).toEqual(["hello"]) }).pipe(Effect.provideService(DemoTag, { getNumbers: () => [0, 1], strings: ["a", "b"], fn: (...args) => Array.from(args), - fnGen: (s) => [s] + fnGen: (s) => [s], + fnParamsUnion: (..._args) => _args }))) it.effect("effect tag with primitives", () => Effect.gen(function*($) {