diff --git a/lib/Result.ts b/lib/Result.ts index 86a5f49..6f0cc23 100644 --- a/lib/Result.ts +++ b/lib/Result.ts @@ -1,17 +1,17 @@ interface ResultBase { - hasError: () => this is ResultError & ResultBase; - hasValue: () => this is ResultValue & ResultBase; + hasError: () => this is ResultError; + hasValue: () => this is ResultValue; unwrapOrThrow: (errorTransformer?: (err: TError) => Error) => TValue; unwrapOrElse: (handleError: (error: Error) => TValue) => TValue; unwrapOrDefault: (defaultValue: TValue) => TValue; } -interface ResultError { +interface ResultError extends ResultBase { error: TError; } -const error = function (err: TError): ResultError & ResultBase { +const error = function (err: TError): ResultError { return { hasError (): boolean { return true; @@ -26,24 +26,24 @@ const error = function (err: TError): ResultError // eslint-disable-next-line @typescript-eslint/no-throw-literal throw err; }, - unwrapOrElse (handleError: (error: TError) => TValue): TValue { + unwrapOrElse (handleError: (error: TError) => TValue): TValue { return handleError(err); }, - unwrapOrDefault (defaultValue: TValue): TValue { + unwrapOrDefault (defaultValue: TValue): TValue { return defaultValue; }, error: err }; }; -interface ResultValue { +interface ResultValue extends ResultBase { value: TValue; } const value: { - (): ResultValue & ResultBase; - (value: TValue): ResultValue & ResultBase; -} = function (val?: TValue): ResultValue & ResultBase { + (): ResultValue; + (value: TValue): ResultValue; +} = function (val?: TValue): ResultValue { return { hasError (): boolean { return false; @@ -64,7 +64,7 @@ const value: { }; }; -type Result = ResultBase; +type Result = ResultValue | ResultError; export type { ResultValue, diff --git a/test/unit/ResultTests.ts b/test/unit/ResultTests.ts index 817b0ed..fc999ee 100644 --- a/test/unit/ResultTests.ts +++ b/test/unit/ResultTests.ts @@ -76,13 +76,15 @@ suite('Result', (): void => { assert.that(resultHasError).is.false(); }); - test(`narrows the type to the error case and discards value type information.`, async (): Promise => { + test('extrapolates value type correctly.', async (): Promise => { const result = getValue(); if (result.hasError()) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const newResult: Result<{ something: 'elseEntirely' }, Error> = result; + return; } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const containedValue: Value = result.value; }); }); @@ -103,17 +105,15 @@ suite('Result', (): void => { assert.that(resultHasValue).is.false(); }); - test(`narrows the type to the value case and discards error type information.`, async (): Promise => { - const result = getValue(); - - interface CustomError extends Error { - bar: string; - } + test('extrapolates error type correctly.', async (): Promise => { + const result = getError(); if (result.hasValue()) { - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const newResult: Result = result; + return; } + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const containedError = result.error; }); }); @@ -246,39 +246,4 @@ suite('Result', (): void => { } }); }); - - test('is assignable to a result with the same error type if the result is known to be an error.', async (): Promise => { - class CustomError extends Error { - public someProp = 0; - } - - // This function compiling it enough for this test. - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const someFunction = function (someResult: Result): Result { - if (someResult.hasError()) { - return someResult; - } - - return error(new CustomError()); - }; - }); - - test('is assignable to a result with the same value type if the result is known to be an value.', async (): Promise => { - class CustomError1 extends Error { - public someProp = 0; - } - class CustomError2 extends Error { - public someOtherProp = 'some string'; - } - - // This function compiling it enough for this test. - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const someFunction = function (someResult: Result): Result { - if (someResult.hasValue()) { - return someResult; - } - - return value(''); - }; - }); });