Skip to content

Commit

Permalink
Support union of parameters in functions in Effect.Tag.Proxy type
Browse files Browse the repository at this point in the history
  • Loading branch information
maksim.khramtsov committed Oct 25, 2024
1 parent 4c965f3 commit 29ca329
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 8 deletions.
5 changes: 5 additions & 0 deletions .changeset/four-items-itch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"effect": patch
---

Support union of parameters in functions in `Effect.Tag.Proxy` type
13 changes: 9 additions & 4 deletions packages/effect/src/Effect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6497,14 +6497,19 @@ export declare namespace Tag {
*/
export type Proxy<Self, Type> = {
[
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<any>) => infer Ret) ?
((...args: Readonly<Args>) => Ret) extends Type[k] ? k : never
: k
]: Type[k] extends (...args: [...infer Args]) => Effect<infer A, infer E, infer R> ?
]: Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => Effect<infer A, infer E, infer R> ?
(...args: Readonly<Args>) => Effect<A, E, Self | R>
: Type[k] extends (...args: [...infer Args]) => infer A ? (...args: Readonly<Args>) => Effect<A, never, Self>
: Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => infer A ?
(...args: Readonly<Args>) => Effect<A, never, Self>
: Type[k] extends Effect<infer A, infer E, infer R> ? Effect<A, E, Self | R>
: Effect<Type[k], never, Self>
: Effect<
Type[k] extends (...args: infer Args extends ReadonlyArray<any>) => any ? [Type[k], Args] : [Type[k], "no"],
never,
Self
>
}
}

Expand Down
15 changes: 11 additions & 4 deletions packages/effect/test/Effect/environment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ class DemoTag extends Effect.Tag("DemoTag")<DemoTag, {
readonly getNumbers: () => Array<number>
readonly strings: Array<string>
readonly fn: (...args: ReadonlyArray<string>) => Array<string>
readonly fnParamsUnion: (
...args: ReadonlyArray<string> | [number] | [false, true]
) => ReadonlyArray<string> | [number] | [false, true]
readonly fnGen: <S>(s: S) => Array<S>
}>() {
}
Expand Down Expand Up @@ -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*($) {
Expand Down

0 comments on commit 29ca329

Please sign in to comment.