• English
  • Asserting Results

    When you've exhausted all possible errors through operations like orElse or andThen, you can use assertSuccess and assertFailure to assert the Result type at compile time. Combined with unwrap and unwrapError, this enables safe value extraction.

    Asserting Success with assertSuccess

    The assertSuccess function asserts that a Result is a Success. This function requires the error type to be never, ensuring at compile time that the Result is guaranteed to be a Success:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const result: Result.Result<number, never>
    result
    :
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, never> =
    import Result
    Result
    .
    const succeed: <42>(value: 42) => Result.Result<42, never> (+1 overload)
    succeed
    (42);
    const
    const success: Result.Success<number>
    success
    =
    import Result
    Result
    .
    const assertSuccess: <Result.Result<number, never>>(result: Result.Result<number, never>) => Result.Success<number>

    Asserts that a Result or ResultAsync is a Success and returns it. This function requires that the result's error type is never, meaning the result is guaranteed to be a Success at the type level. If the result is a Failure at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the error type.@paramresult - The Result or ResultAsync to assert as a Success. The error type must be never.@returnsThe Success result or a Promise of Success result.@throws{Error} If the result is a Failure at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.succeed(42);
    const success = Result.assertSuccess(result);
    // success: { type: 'Success', value: 42 }
    @example

    Type-safe usage after narrowing error type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.succeed(42);
    const value = Result.pipe(
    getResult(),
    Result.orElse(() => Result.succeed(0)), // Error type becomes never
    Result.assertSuccess, // Type-safe: error type is now never
    Result.unwrap(), // Safe unwrap after assertion
    );
    @seeunwrap - Use with assertSuccess to safely unwrap success values.@categoryAssertions
    assertSuccess
    (
    const result: Result.Result<number, never>
    result
    );
    // success: { type: 'Success', value: 42 }

    When Error Type is Not never

    If the error type is not never, TypeScript will raise a compilation error:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const result: Result.Result<number, string>
    result
    :
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, string> =
    import Result
    Result
    .
    const succeed: <42>(value: 42) => Result.Result<42, never> (+1 overload)
    succeed
    (42);
    // ❌ TypeScript error: error type is string, not never const
    const success: Promise<Result.Success<any>>
    success
    =
    import Result
    Result
    .
    const assertSuccess: <Result.ResultMaybeAsync<any, never>>(result: Result.ResultMaybeAsync<any, never>) => Promise<Result.Success<any>>

    Asserts that a Result or ResultAsync is a Success and returns it. This function requires that the result's error type is never, meaning the result is guaranteed to be a Success at the type level. If the result is a Failure at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the error type.@paramresult - The Result or ResultAsync to assert as a Success. The error type must be never.@returnsThe Success result or a Promise of Success result.@throws{Error} If the result is a Failure at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.succeed(42);
    const success = Result.assertSuccess(result);
    // success: { type: 'Success', value: 42 }
    @example

    Type-safe usage after narrowing error type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.succeed(42);
    const value = Result.pipe(
    getResult(),
    Result.orElse(() => Result.succeed(0)), // Error type becomes never
    Result.assertSuccess, // Type-safe: error type is now never
    Result.unwrap(), // Safe unwrap after assertion
    );
    @seeunwrap - Use with assertSuccess to safely unwrap success values.@categoryAssertions
    assertSuccess
    (result);
    Argument of type 'Result<number, string>' is not assignable to parameter of type 'ResultMaybeAsync<any, never>'. Type 'Failure<string>' is not assignable to type 'ResultMaybeAsync<any, never>'. Type 'Failure<string>' is not assignable to type 'Failure<never> | Promise<Result<any, never>>'. Type 'Failure<string>' is not assignable to type 'Failure<never>'. Type 'string' is not assignable to type 'never'.

    Making Error Type never with orElse

    Use orElse to handle all errors and narrow the error type to never:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    declare const
    const getResult: () => Result.Result<number, "NotFound" | "NetworkError">
    getResult
    : () =>
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, 'NotFound' | 'NetworkError'>;
    const
    const result: Result.Success<number>
    result
    =
    import Result
    Result
    .
    const pipe: <Result.Result<number, "NotFound" | "NetworkError">, Result.Result<number, never>, Result.Success<number>>(a: Result.Result<number, "NotFound" | "NetworkError">, ab: (a: Result.Result<number, "NotFound" | "NetworkError">) => Result.Result<number, never>, bc: (b: Result.Result<number, never>) => Result.Success<number>) => Result.Success<number> (+25 overloads)
    pipe
    (
    const getResult: () => Result.Result<number, "NotFound" | "NetworkError">
    getResult
    (),
    import Result
    Result
    .
    const orElse: <Result.Result<number, "NotFound" | "NetworkError">, Result.Result<0, never>>(fn: (a: "NotFound" | "NetworkError") => Result.Result<0, never>) => (result: Result.Result<number, "NotFound" | "NetworkError">) => Result.Result<number, never> (+1 overload)
    orElse
    ((
    error: "NotFound" | "NetworkError"
    error
    ) => {
    // Handle all errors and return a fallback value return
    import Result
    Result
    .
    const succeed: <0>(value: 0) => Result.Result<0, never> (+1 overload)
    succeed
    (0);
    }), // Error type is now never
    import Result
    Result
    .
    const assertSuccess: <R extends Result.ResultMaybeAsync<any, never>>(result: R) => true extends HasPromise<R> ? Promise<Result.Success<Result.InferSuccess<R>>> : Result.Success<Result.InferSuccess<R>>

    Asserts that a Result or ResultAsync is a Success and returns it. This function requires that the result's error type is never, meaning the result is guaranteed to be a Success at the type level. If the result is a Failure at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the error type.@paramresult - The Result or ResultAsync to assert as a Success. The error type must be never.@returnsThe Success result or a Promise of Success result.@throws{Error} If the result is a Failure at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.succeed(42);
    const success = Result.assertSuccess(result);
    // success: { type: 'Success', value: 42 }
    @example

    Type-safe usage after narrowing error type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.succeed(42);
    const value = Result.pipe(
    getResult(),
    Result.orElse(() => Result.succeed(0)), // Error type becomes never
    Result.assertSuccess, // Type-safe: error type is now never
    Result.unwrap(), // Safe unwrap after assertion
    );
    @seeunwrap - Use with assertSuccess to safely unwrap success values.@categoryAssertions
    assertSuccess
    ,
    ); // result: { type: 'Success', value: number }

    Asserting Failure with assertFailure

    The assertFailure function is the opposite—it asserts that a Result is a Failure. This function requires the success type to be never:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const result: Result.Result<never, string>
    result
    :
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <never, string> =
    import Result
    Result
    .
    const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
    fail
    ('error');
    const
    const failure: Result.Failure<string>
    failure
    =
    import Result
    Result
    .
    const assertFailure: <Result.Result<never, string>>(result: Result.Result<never, string>) => Result.Failure<string>

    Asserts that a Result or ResultAsync is a Failure and returns it. This function requires that the result's success type is never, meaning the result is guaranteed to be a Failure at the type level. If the result is a Success at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the success type.@paramresult - The Result or ResultAsync to assert as a Failure. The success type must be never.@returnsThe Failure result or a Promise of Failure result.@throws{Error} If the result is a Success at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.fail('error');
    const failure = Result.assertFailure(result);
    // failure: { type: 'Failure', error: 'error' }
    @example

    Type-safe usage after narrowing success type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.fail('error');
    const value = Result.pipe(
    getResult(),
    Result.andThen(() => Result.fail('die')), // Success type becomes never
    Result.assertFailure, // Type-safe: success type is now never
    Result.unwrapError(), // Safe unwrap after assertion
    );
    @seeunwrapError - Use with assertFailure to safely unwrap error values.@categoryAssertions
    assertFailure
    (
    const result: Result.Result<never, string>
    result
    );
    // failure: { type: 'Failure', error: 'error' }

    When Success Type is Not never

    If the success type is not never, TypeScript will raise a compilation error:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    const
    const result: Result.Result<number, string>
    result
    :
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, string> =
    import Result
    Result
    .
    const fail: <"error">(error: "error") => Result.Result<never, "error"> (+1 overload)
    fail
    ('error');
    // ❌ TypeScript error: success type is number, not never const
    const failure: Promise<Result.Failure<any>>
    failure
    =
    import Result
    Result
    .
    const assertFailure: <Result.ResultMaybeAsync<never, any>>(result: Result.ResultMaybeAsync<never, any>) => Promise<Result.Failure<any>>

    Asserts that a Result or ResultAsync is a Failure and returns it. This function requires that the result's success type is never, meaning the result is guaranteed to be a Failure at the type level. If the result is a Success at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the success type.@paramresult - The Result or ResultAsync to assert as a Failure. The success type must be never.@returnsThe Failure result or a Promise of Failure result.@throws{Error} If the result is a Success at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.fail('error');
    const failure = Result.assertFailure(result);
    // failure: { type: 'Failure', error: 'error' }
    @example

    Type-safe usage after narrowing success type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.fail('error');
    const value = Result.pipe(
    getResult(),
    Result.andThen(() => Result.fail('die')), // Success type becomes never
    Result.assertFailure, // Type-safe: success type is now never
    Result.unwrapError(), // Safe unwrap after assertion
    );
    @seeunwrapError - Use with assertFailure to safely unwrap error values.@categoryAssertions
    assertFailure
    (result);
    Argument of type 'Result<number, string>' is not assignable to parameter of type 'ResultMaybeAsync<never, any>'. Type 'Success<number>' is not assignable to type 'ResultMaybeAsync<never, any>'. Type 'Success<number>' is not assignable to type 'Success<never> | Promise<Result<never, any>>'. Type 'Success<number>' is not assignable to type 'Success<never>'. Type 'number' is not assignable to type 'never'.

    Making Success Type never with andThen

    Use andThen to make all paths fail and narrow the success type to never:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    declare const
    const getResult: () => Result.Result<number, string>
    getResult
    : () =>
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, string>;
    const
    const result: Result.Failure<string>
    result
    =
    import Result
    Result
    .
    const pipe: <Result.Result<number, string>, Result.Result<never, string>, Result.Failure<string>>(a: Result.Result<number, string>, ab: (a: Result.Result<number, string>) => Result.Result<never, string>, bc: (b: Result.Result<never, string>) => Result.Failure<string>) => Result.Failure<string> (+25 overloads)
    pipe
    (
    const getResult: () => Result.Result<number, string>
    getResult
    (),
    import Result
    Result
    .
    const andThen: <Result.Result<number, string>, Result.Result<never, "converted error">>(fn: (a: number) => Result.Result<never, "converted error">) => (result: Result.Result<number, string>) => Result.Result<never, string> (+1 overload)
    andThen
    (() => {
    // All paths lead to failure return
    import Result
    Result
    .
    const fail: <"converted error">(error: "converted error") => Result.Result<never, "converted error"> (+1 overload)
    fail
    ('converted error');
    }), // Success type is now never
    import Result
    Result
    .
    const assertFailure: <R extends Result.ResultMaybeAsync<never, any>>(result: R) => true extends HasPromise<R> ? Promise<Result.Failure<Result.InferFailure<R>>> : Result.Failure<Result.InferFailure<R>>

    Asserts that a Result or ResultAsync is a Failure and returns it. This function requires that the result's success type is never, meaning the result is guaranteed to be a Failure at the type level. If the result is a Success at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the success type.@paramresult - The Result or ResultAsync to assert as a Failure. The success type must be never.@returnsThe Failure result or a Promise of Failure result.@throws{Error} If the result is a Success at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.fail('error');
    const failure = Result.assertFailure(result);
    // failure: { type: 'Failure', error: 'error' }
    @example

    Type-safe usage after narrowing success type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.fail('error');
    const value = Result.pipe(
    getResult(),
    Result.andThen(() => Result.fail('die')), // Success type becomes never
    Result.assertFailure, // Type-safe: success type is now never
    Result.unwrapError(), // Safe unwrap after assertion
    );
    @seeunwrapError - Use with assertFailure to safely unwrap error values.@categoryAssertions
    assertFailure
    ,
    ); // result: { type: 'Failure', error: string }

    Safe Unwrapping with assertSuccess + unwrap

    By combining assertSuccess with unwrap, you can safely extract values from a Result. Since the error type is never after the assertion, unwrap is guaranteed not to throw:

    import { 
    import Result
    Result
    } from '@praha/byethrow';
    declare const
    const getResult: () => Result.Result<number, "NotFound" | "NetworkError">
    getResult
    : () =>
    import Result
    Result
    .
    type Result<T, E> = Result.Success<T> | Result.Failure<E>

    A union type representing either a success or a failure.

    @typeParamT - The type of the Success value.@typeParamE - The type of the Failure value.@example
    import { Result } from '@praha/byethrow';
    
    const doSomething = (): Result.Result<number, string> => {
      return Math.random() > 0.5
        ? { type: 'Success', value: 10 }
        : { type: 'Failure', error: 'Oops' };
    };
    @categoryCore Types
    Result
    <number, 'NotFound' | 'NetworkError'>;
    const
    const value: number
    value
    =
    import Result
    Result
    .
    const pipe: <Result.Result<number, "NotFound" | "NetworkError">, Result.Result<number, never>, Result.Success<number>, number>(a: Result.Result<number, "NotFound" | "NetworkError">, ab: (a: Result.Result<number, "NotFound" | "NetworkError">) => Result.Result<number, never>, bc: (b: Result.Result<number, never>) => Result.Success<number>, cd: (c: Result.Success<number>) => number) => number (+25 overloads)
    pipe
    (
    const getResult: () => Result.Result<number, "NotFound" | "NetworkError">
    getResult
    (),
    import Result
    Result
    .
    const orElse: <Result.Result<number, "NotFound" | "NetworkError">, Result.Result<0, never>>(fn: (a: "NotFound" | "NetworkError") => Result.Result<0, never>) => (result: Result.Result<number, "NotFound" | "NetworkError">) => Result.Result<number, never> (+1 overload)
    orElse
    (() =>
    import Result
    Result
    .
    const succeed: <0>(value: 0) => Result.Result<0, never> (+1 overload)
    succeed
    (0)), // Handle all errors
    import Result
    Result
    .
    const assertSuccess: <R extends Result.ResultMaybeAsync<any, never>>(result: R) => true extends HasPromise<R> ? Promise<Result.Success<Result.InferSuccess<R>>> : Result.Success<Result.InferSuccess<R>>

    Asserts that a Result or ResultAsync is a Success and returns it. This function requires that the result's error type is never, meaning the result is guaranteed to be a Success at the type level. If the result is a Failure at runtime, throws an error.

    @function@typeParamR - The result type that extends ResultMaybeAsync with never as the error type.@paramresult - The Result or ResultAsync to assert as a Success. The error type must be never.@returnsThe Success result or a Promise of Success result.@throws{Error} If the result is a Failure at runtime.@example
    import { Result } from '@praha/byethrow';
    
    const result = Result.succeed(42);
    const success = Result.assertSuccess(result);
    // success: { type: 'Success', value: 42 }
    @example

    Type-safe usage after narrowing error type

    import { Result } from '@praha/byethrow';
    
    const getResult = (): Result.Result<number, string> => Result.succeed(42);
    const value = Result.pipe(
    getResult(),
    Result.orElse(() => Result.succeed(0)), // Error type becomes never
    Result.assertSuccess, // Type-safe: error type is now never
    Result.unwrap(), // Safe unwrap after assertion
    );
    @seeunwrap - Use with assertSuccess to safely unwrap success values.@categoryAssertions
    assertSuccess
    , // Error type is now never
    import Result
    Result
    .
    const unwrap: <Result.Success<number>>() => (result: Result.Success<number>) => number (+3 overloads)
    unwrap
    (), // Safe: guaranteed not to throw
    ); // value: number

    This pattern is particularly useful at application boundaries where you want to ensure type safety while extracting the final value.

    Difference from Runtime Type Guards

    It's important to understand the difference between assertSuccess/assertFailure and isSuccess/isFailure:

    FunctionPurposeThrows on Mismatch?
    isSuccessRuntime check, returns booleanNo
    isFailureRuntime check, returns booleanNo
    assertSuccessCompile-time assertion (requires never)Yes (if type is wrong)
    assertFailureCompile-time assertion (requires never)Yes (if type is wrong)
    • isSuccess/isFailure: Use when you need to branch based on the Result type at runtime
    • assertSuccess/assertFailure: Use when you've already ensured the Result type at compile time and want to assert it

    References

    FunctionPurpose
    assertSuccess(result)Assert that a Result is Success (requires error type to be never)
    assertFailure(result)Assert that a Result is Failure (requires success type to be never)