diff --git a/src/result.spec.ts b/src/result.spec.ts index c1dba37..f4192fe 100644 --- a/src/result.spec.ts +++ b/src/result.spec.ts @@ -48,17 +48,42 @@ 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('#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', () => { 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. */