From cae742417beaaa03f429ab7d62b496630f0d9757 Mon Sep 17 00:00:00 2001 From: Sergei Zharinov <zharinov@users.noreply.github.com> Date: Sun, 24 Nov 2024 14:45:56 -0300 Subject: [PATCH] refactor: Error type narrowing for `Result` class (#32705) --- lib/util/result.spec.ts | 19 ++++++++------- lib/util/result.ts | 51 ++++++++++++++++++----------------------- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/lib/util/result.spec.ts b/lib/util/result.spec.ts index 775c077ebd..61b0957ca8 100644 --- a/lib/util/result.spec.ts +++ b/lib/util/result.spec.ts @@ -240,9 +240,8 @@ describe('util/result', () => { }); it('converts error to Result', () => { - const result = Result.err<string>('oops').catch(() => - Result.ok<number>(42), - ); + const error: Result<number, string> = Result.err<string>('oops'); + const result = error.catch((_err) => Result.ok<number>(42)); expect(result).toEqual(Result.ok(42)); }); @@ -600,15 +599,15 @@ describe('util/result', () => { describe('Catch', () => { it('converts error to AsyncResult', async () => { - const result = await Result.err<string>('oops').catch(() => - AsyncResult.ok(42), - ); + const error: Result<number, string> = Result.err<string>('oops'); + const result = await error.catch(() => AsyncResult.ok(42)); expect(result).toEqual(Result.ok(42)); }); it('converts error to Promise', async () => { const fallback = Promise.resolve(Result.ok(42)); - const result = await Result.err<string>('oops').catch(() => fallback); + const error: Result<number, string> = Result.err<string>('oops'); + const result = await error.catch(() => fallback); expect(result).toEqual(Result.ok(42)); }); @@ -619,9 +618,9 @@ describe('util/result', () => { }); it('converts AsyncResult error to Result', async () => { - const result = await AsyncResult.err<string>('oops').catch(() => - AsyncResult.ok<number>(42), - ); + const error: AsyncResult<number, string> = + AsyncResult.err<string>('oops'); + const result = await error.catch(() => AsyncResult.ok<number>(42)); expect(result).toEqual(Result.ok(42)); }); }); diff --git a/lib/util/result.ts b/lib/util/result.ts index 7237d0d33d..f6649b6502 100644 --- a/lib/util/result.ts +++ b/lib/util/result.ts @@ -480,28 +480,23 @@ export class Result<T extends Val, E extends Val = Error> { } catch<U extends Val = T, EE extends Val = E>( - fn: (err: E) => Result<U, E | EE>, - ): Result<T | U, E | EE>; + fn: (err: E) => Result<U, EE>, + ): Result<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( - fn: (err: E) => AsyncResult<U, E | EE>, - ): AsyncResult<T | U, E | EE>; + fn: (err: E) => AsyncResult<U, EE>, + ): AsyncResult<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( - fn: (err: E) => Promise<Result<U, E | EE>>, - ): AsyncResult<T | U, E | EE>; + fn: (err: E) => Promise<Result<U, EE>>, + ): AsyncResult<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( - fn: ( - err: E, - ) => - | Result<U, E | EE> - | AsyncResult<U, E | EE> - | Promise<Result<U, E | EE>>, - ): Result<T | U, E | EE> | AsyncResult<T | U, E | EE> { + fn: (err: E) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>, + ): Result<T | U, EE> | AsyncResult<T | U, EE> { if (this.res.ok) { - return this; + return this as never; } if (this.res._uncaught) { - return this; + return this as never; } try { @@ -833,25 +828,23 @@ export class AsyncResult<T extends Val, E extends Val> } catch<U extends Val = T, EE extends Val = E>( - fn: (err: NonNullable<E>) => Result<U, E | EE>, - ): AsyncResult<T | U, E | EE>; + fn: (err: NonNullable<E>) => Result<U, EE>, + ): AsyncResult<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( - fn: (err: NonNullable<E>) => AsyncResult<U, E | EE>, - ): AsyncResult<T | U, E | EE>; + fn: (err: NonNullable<E>) => AsyncResult<U, EE>, + ): AsyncResult<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( - fn: (err: NonNullable<E>) => Promise<Result<U, E | EE>>, - ): AsyncResult<T | U, E | EE>; + fn: (err: NonNullable<E>) => Promise<Result<U, EE>>, + ): AsyncResult<T | U, EE>; catch<U extends Val = T, EE extends Val = E>( fn: ( err: NonNullable<E>, - ) => - | Result<U, E | EE> - | AsyncResult<U, E | EE> - | Promise<Result<U, E | EE>>, - ): AsyncResult<T | U, E | EE> { - const caughtAsyncResult = this.asyncResult.then((result) => - // eslint-disable-next-line promise/no-nesting - result.catch(fn as never), + ) => Result<U, EE> | AsyncResult<U, EE> | Promise<Result<U, EE>>, + ): AsyncResult<T | U, EE> { + const caughtAsyncResult: Promise<Result<T, EE>> = this.asyncResult.then( + (result) => + // eslint-disable-next-line promise/no-nesting + result.catch(fn as never), ); return AsyncResult.wrap(caughtAsyncResult); } -- GitLab