From 3349fc08a153cb4e601d2d7796f3cb635e305fb0 Mon Sep 17 00:00:00 2001 From: Sergey Slipchenko Date: Sat, 17 Feb 2024 14:26:02 +0400 Subject: [PATCH 1/2] chore: improve flatMapOk test --- src/result.spec.ts | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/result.spec.ts b/src/result.spec.ts index c1dba37..3ce4cfa 100644 --- a/src/result.spec.ts +++ b/src/result.spec.ts @@ -48,17 +48,24 @@ describe('Result', () => { }); it('#flatMapOk', () => { - const matched = Result.Ok('anything') - .flatMapOk(s => - s === 'something' ? Result.Ok(s) : Result.Err('Something failed'), - ) - .match({ - Err: err => err, - Ok: value => value, - }); + const matched1 = Result.Ok('anything').flatMapOk(s => + s === 'anything' ? Result.Ok(42) : Result.Err('No'), + ); - expectTypeOf(matched).toEqualTypeOf(); - expect(matched).toBe('Something failed'); + expectTypeOf(matched1).toEqualTypeOf>(); + expect(matched1.match({ Err: err => err, Ok: value => value })).toBe(42); + + const matched2 = Result.Err('input-error').flatMapOk(value => + value === 'anything' ? Result.Ok(42) : Result.Err('something'), + ); + + expectTypeOf(matched2).toEqualTypeOf< + Result + >(); + + expect(matched2.match({ Err: err => err, Ok: value => value })).toBe( + 'input-error', + ); }); it('#getOk', () => { From da79feeb01f2fb1b83e89cf9193834424ab66631 Mon Sep 17 00:00:00 2001 From: Sergey Slipchenko Date: Sat, 17 Feb 2024 14:27:40 +0400 Subject: [PATCH 2/2] feat: add Result#flatMapErr --- src/result.spec.ts | 18 ++++++++++++++++++ src/result.ts | 15 +++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/src/result.spec.ts b/src/result.spec.ts index 3ce4cfa..f4192fe 100644 --- a/src/result.spec.ts +++ b/src/result.spec.ts @@ -68,6 +68,24 @@ describe('Result', () => { ); }); + it('#flatMapErr', () => { + const matched1 = Result.Err<'input-error' | 'critical-error'>( + 'input-error', + ).flatMapErr(err => + err === 'input-error' ? Result.Ok(42) : Result.Err(err), + ); + + expectTypeOf(matched1).toEqualTypeOf>(); + expect(matched1.match({ Err: err => err, Ok: value => value })).toBe(42); + + const matched2 = Result.Ok('42').flatMapErr(err => + err === 'input-error' ? Result.Ok(42) : Result.Err('error'), + ); + + expectTypeOf(matched2).toEqualTypeOf>(); + expect(matched2.match({ Err: err => err, Ok: value => value })).toBe('42'); + }); + it('#getOk', () => { const matchedSuccess = Result.Ok(42) .getOk() diff --git a/src/result.ts b/src/result.ts index 3c9503a..e47cc38 100644 --- a/src/result.ts +++ b/src/result.ts @@ -104,6 +104,21 @@ export class Result { }); } + /** + * Apply an arbitrary transformation to a failure value inside the box and + * return a new box with the result of that transformation. + * As opposed to `mapErr`, `f` is required to return a new box, not just a + * value. + * This can be useful if you want to turn `Result.Err` into `Result.Ok` + * depending on it's value + */ + flatMapErr(f: (err: E) => Result) { + return this.match>({ + Err: err => f(err), + Ok: Result.Ok, + }); + } + /** * Turn this `Result` into a `Maybe` of a success value. */