From a047af99447dfffc729e9c8ef0ca143537927e91 Mon Sep 17 00:00:00 2001 From: Tim Date: Thu, 27 Jun 2024 14:32:13 +1200 Subject: [PATCH] fix using unions with Match.withReturnType (#3099) --- .changeset/brown-wasps-exist.md | 5 ++++ packages/effect/src/Match.ts | 8 ++--- packages/effect/src/internal/matcher.ts | 39 +++++++++++++------------ packages/effect/test/Match.test.ts | 21 +++++++++++++ 4 files changed, 50 insertions(+), 23 deletions(-) create mode 100644 .changeset/brown-wasps-exist.md diff --git a/.changeset/brown-wasps-exist.md b/.changeset/brown-wasps-exist.md new file mode 100644 index 0000000000..7e6a2dd126 --- /dev/null +++ b/.changeset/brown-wasps-exist.md @@ -0,0 +1,5 @@ +--- +"effect": patch +--- + +fix using unions with Match.withReturnType diff --git a/packages/effect/src/Match.ts b/packages/effect/src/Match.ts index e134cc3e5e..28c7f94f7f 100644 --- a/packages/effect/src/Match.ts +++ b/packages/effect/src/Match.ts @@ -140,7 +140,7 @@ export const typeTags: () => < */ export const withReturnType: () => ( self: Matcher -) => Ret extends ([A] extends [never] ? any : A) ? Matcher +) => [Ret] extends [[A] extends [never] ? any : A] ? Matcher : "withReturnType constraint does not extend Result type" = internal.withReturnType /** @@ -496,11 +496,11 @@ export const instanceOfUnsafe: any>( * @category conversions * @since 1.0.0 */ -export const orElse: ( - f: (b: RA) => B +export const orElse: Ret>( + f: F ) => ( self: Matcher -) => [Pr] extends [never] ? (input: I) => Unify : Unify = internal.orElse +) => [Pr] extends [never] ? (input: I) => Unify | A> : Unify | A> = internal.orElse /** * @category conversions diff --git a/packages/effect/src/internal/matcher.ts b/packages/effect/src/internal/matcher.ts index b9e06b8b44..3ba748ebd4 100644 --- a/packages/effect/src/internal/matcher.ts +++ b/packages/effect/src/internal/matcher.ts @@ -239,11 +239,11 @@ export const typeTags = () => } /** @internal */ -export const withReturnType = - () => - (self: Matcher): Ret extends ([A] extends [never] ? any - : A) ? Matcher - : "withReturnType constraint does not extend Result type" => self as any +export const withReturnType = () => +(self: Matcher): [Ret] extends [ + [A] extends [never] ? any : A +] ? Matcher + : "withReturnType constraint does not extend Result type" => self as any /** @internal */ export const when = < @@ -512,23 +512,24 @@ export const instanceOfUnsafe: any>( ) => SafeRefinement, InstanceType> = instanceOf /** @internal */ -export const orElse = (f: (b: RA) => B) => -( - self: Matcher -): [Pr] extends [never] ? (input: I) => Unify : Unify => { - const result = either(self) +export const orElse = + Ret>(f: F) => + (self: Matcher): [Pr] extends [never] ? (input: I) => Unify | A> + : Unify | A> => + { + const result = either(self) + + if (Either.isEither(result)) { + // @ts-expect-error + return result._tag === "Right" ? result.right : f(result.left) + } - if (Either.isEither(result)) { // @ts-expect-error - return result._tag === "Right" ? result.right : f(result.left) - } - - // @ts-expect-error - return (input: I) => { - const a = result(input) - return a._tag === "Right" ? a.right : f(a.left) + return (input: I) => { + const a = result(input) + return a._tag === "Right" ? a.right : f(a.left) + } } -} /** @internal */ export const orElseAbsurd = ( diff --git a/packages/effect/test/Match.test.ts b/packages/effect/test/Match.test.ts index 0884aa5bd8..9f4af93743 100644 --- a/packages/effect/test/Match.test.ts +++ b/packages/effect/test/Match.test.ts @@ -819,4 +819,25 @@ describe("Match", () => { M.orElse(() => "else") ) }) + + it("withReturnType union", () => { + const match = pipe( + M.type(), + M.withReturnType<"a" | "b">(), + M.when("A", (_) => "a"), + M.orElse((_) => "b") + ) + expect(match("A")).toEqual("a") + expect(match("a")).toEqual("b") + }) + + it("withReturnType union mismatch", () => { + pipe( + M.type(), + M.withReturnType<"a" | "b">(), + M.when("A", (_) => "a"), + // @ts-expect-error + M.orElse((_) => "c") + ) + }) })