From 2144de5b16d5a68bfd132bf0c62abfcb6862bdf8 Mon Sep 17 00:00:00 2001 From: Cristian Velasquez Ramos Date: Wed, 2 Aug 2023 19:55:29 -0400 Subject: [PATCH] allow branching .match --- .changeset/slow-worms-grin.md | 5 +++++ lib/src/option.ts | 8 ++++---- lib/src/result.ts | 8 ++++---- lib/src/task.test.ts | 9 ++------- lib/src/task.ts | 16 ++++++++-------- 5 files changed, 23 insertions(+), 23 deletions(-) create mode 100644 .changeset/slow-worms-grin.md diff --git a/.changeset/slow-worms-grin.md b/.changeset/slow-worms-grin.md new file mode 100644 index 0000000..95a6d8b --- /dev/null +++ b/.changeset/slow-worms-grin.md @@ -0,0 +1,5 @@ +--- +"ftld": patch +--- + +make .match branches a union for potentially unrelated types diff --git a/lib/src/option.ts b/lib/src/option.ts index a40b3a8..16dbf49 100644 --- a/lib/src/option.ts +++ b/lib/src/option.ts @@ -2,9 +2,9 @@ import { _value, _tag, TAGS } from "./internals"; import type { Result } from "./result"; import { UnwrapNoneError, identity, isResult } from "./utils"; -type OptionMatcher = { +type OptionMatcher = { None: () => B; - Some: (value: A) => B; + Some: (value: A) => C; } & {}; export class Some { @@ -59,7 +59,7 @@ export class Some { /** * Executes the appropriate function from the provided matcher based on the type of the Option. */ - match(cases: OptionMatcher): B { + match(cases: OptionMatcher): B | C { return cases.Some(this[_value]); } @@ -121,7 +121,7 @@ export class None { /** * Executes the appropriate function from the provided matcher based on the type of the Option. */ - match(cases: OptionMatcher): B { + match(cases: OptionMatcher): B | C { return cases.None(); } diff --git a/lib/src/result.ts b/lib/src/result.ts index fffef3a..a56202e 100644 --- a/lib/src/result.ts +++ b/lib/src/result.ts @@ -2,9 +2,9 @@ import { _value, _tag, TAGS } from "./internals"; import { UnknownError, identity, isOption } from "./utils"; import type { Option } from "./option"; -type ResultMatcher = { +type ResultMatcher = { Err: (value: E) => B; - Ok: (value: A) => B; + Ok: (value: A) => C; } & {}; export class Ok { @@ -91,7 +91,7 @@ export class Ok { /** * Matches the Result using provided functions and returns the result. */ - match(cases: ResultMatcher): B { + match(cases: ResultMatcher): B | C { return cases.Ok(this[_value]); } @@ -203,7 +203,7 @@ export class Err { /** * Matches the Result using provided functions and returns the result. */ - match(cases: ResultMatcher): B { + match(cases: ResultMatcher): B | C { return cases.Err(this[_value]); } diff --git a/lib/src/task.test.ts b/lib/src/task.test.ts index 72ab30a..e048641 100644 --- a/lib/src/task.test.ts +++ b/lib/src/task.test.ts @@ -891,13 +891,7 @@ describe.concurrent("Task", () => { it("should accumulate errors", async () => { const values = [1, 2, 3, 4]; const tasks: SyncTask[] = values.map( - (x) => - x > 2 - ? Task.Err(new SomeError()) - : Task.from( - () => x * 2, - () => new OtherError() - ) + (x) => (x > 2 ? Task.Err(new SomeError()) : Task.Ok(x * 2)) ); const asyncTasks = tasks.map((task) => task.flatMap(async (x) => Result.Ok(x)) @@ -918,6 +912,7 @@ describe.concurrent("Task", () => { expect(asyncTask.run()).toBeInstanceOf(Promise); expect(result.isErr()).toBeTruthy(); expect(result.unwrapErr().length).toBe(2); + expect(result.unwrapErr()).toEqual([new SomeError(), new SomeError()]); }); it("should accumulate errors when provided a record", async () => { diff --git a/lib/src/task.ts b/lib/src/task.ts index 75ac77d..c85e545 100644 --- a/lib/src/task.ts +++ b/lib/src/task.ts @@ -99,11 +99,11 @@ export type AsyncTask = { /** * Matches the Task's Result and executes a function based on its variant (Ok or Err). */ - match(cases: { + match(cases: { Ok: (a: A) => Promise; - Err: (e: E) => Promise; - }): Promise; - match(cases: { Ok: (a: A) => B; Err: (e: E) => B }): Promise; + Err: (e: E) => Promise; + }): Promise; + match(cases: { Ok: (a: A) => B; Err: (e: E) => C }): Promise; /** * Returns the successful value or throws an error if the Task is Err. @@ -226,11 +226,11 @@ export type SyncTask = { /** * Matches the Task's Result and executes a function based on its variant (Ok or Err). */ - match(cases: { + match(cases: { Ok: (a: A) => Promise; - Err: (e: E) => Promise; - }): Promise; - match(cases: { Ok: (a: A) => B; Err: (e: E) => B }): B; + Err: (e: E) => Promise; + }): Promise; + match(cases: { Ok: (a: A) => B; Err: (e: E) => C }): B | C; /** * Returns the successful value or throws an error if the Task is Err.