/** biome-ignore-all lint/complexity/noBannedTypes: No alternative */
/**
 * Defines methods for a `Result` type, providing type-safe operations for checking and extracting values.
 * @template T - The type of the success value.
 * @template E - The error type, must extend `Error`.
 * @template U - The return type of `unwrap`, typically `T` for `OkState` or `never` for `ErrorState`.
 */
interface ResultMethods<T, E extends Error> {
    /**
     * Returns the provided `Result` if this value is `Ok`, otherwise preserves the current `Err`.
     * This is the eager counterpart to `andThen`.
     * @template U - The success type of the provided `Result`.
     * @param {Result<U, E>} result - The `Result` to return when this value is `Ok`.
     * @returns {Result<U, E>} The provided `result` when `Ok`, or the current error when `Err`.
     * @example
     * const ok = Ok(1).and(Ok("done"));
     * // ok: Result<string, Error> = Ok("done")
     *
     * const err = Err<string>(new Error("Failed")).and(Ok("done"));
     * // err: Result<string, Error> = Err(Error("Failed"))
     */
    and<U>(result: Result<U, E>): Result<U, E>;
    /**
     * Chains a transformation by passing the `Ok` value to a function that returns a new `Result`, preserving the `Err` state if present.
     * This is the Rust-style composition method for sequencing operations that may fail.
     * @template U - The type of the success value in the returned `Result`.
     * @param {(value: T) => Result<U, E>} fn - A function that takes the `Ok` value of type `T` and returns a new `Result<U, E>`.
     * @returns {Result<U, E>} A new `Result<U, E>`: the result of `fn` if the original `Result` is `Ok`, or the same `Err` state if the original `Result` is `Err`.
     * @example
     * // Chaining transformations
     * const result: Result<number, Error> = Ok(5);
     * const chained = result
     *   .andThen(x => Ok(x * 2)) // Result<number, Error> = Ok(10)
     *   .andThen(x => Ok(x.toString())); // Result<string, Error> = Ok("10")
     * if (chained.isOk()) {
     *   console.log(chained.ok); // "10"
     * }
     *
     * // Preserving Err state
     * const error: Result<number, Error> = Err(new Error("Failed"));
     * const chainedError = error.andThen(x => Ok(x * 2));
     * // Result<number, Error> = Err(Error("Failed"))
     * if (chainedError.isError()) {
     *   console.log(chainedError.error.message); // "Failed"
     * }
     */
    andThen<U>(fn: (value: T) => Result<U, E>): Result<U, E>;
    /**
     * Extracts the success value from an `OkState<T>` result.
     * If the result is an `ErrorState<E>`, it throws a `CustomError` with the provided message,
     * and the original error from `ErrorState<E>` is passed as the `cause` property.
     * @returns {T} The success value if `OkState<T>`.
     * @throws {CustomError} Throws a `CustomError` containing the provided message and the original error as its cause, if the result is in the Error state.
     */
    expect(message: string): T;
    /**
     * Extracts the error value from an `Err` result.
     * If the result is `Ok`, it throws a `CustomError` with the provided message.
     * @param {string} message - Message used when the result unexpectedly contains an `Ok` value.
     * @returns {E} The contained error when the result is `Err`.
     * @throws {CustomError} Throws when the result is `Ok`.
     */
    expectErr(message: string): E;
    /**
     * Runs a side-effect function on the success value when the result is `Ok`.
     * The original `Result` is returned unchanged.
     * @param {(value: T) => void} fn - Function invoked with the `Ok` value.
     * @returns {Result<T, E>} The original result.
     * @example
     * const result = Ok(42).inspect(value => console.log(value));
     * // logs 42 and returns the same Result
     */
    inspect(fn: (value: T) => void): Result<T, E>;
    /**
     * Runs a side-effect function on the error value when the result is `Err`.
     * The original `Result` is returned unchanged.
     * @param {(error: E) => void} fn - Function invoked with the `Err` value.
     * @returns {Result<T, E>} The original result.
     * @example
     * const result = Err(new Error("Failed")).inspectErr(error => console.error(error.message));
     * // logs "Failed" and returns the same Result
     */
    inspectErr(fn: (error: E) => void): Result<T, E>;
    /**
     * Checks if the result is in the `Ok` state (contains a value and no error).
     * @returns `true` if the result is `Ok`, narrowing the type to `OkState<T, E>`.
     */
    isOk(): this is OkState<T, E>;
    /**
     * Checks if the result is in the `Err` state (contains an error and no value).
     * @returns `true` if the result is `Err`, narrowing the type to `ErrorState<E, T>`.
     */
    isError(): this is ErrorState<E, T>;
    /**
     * Transforms the success value of a `Result` using the provided function, preserving the error if in the `Err` state.
     * @template U - The type of the transformed success value.
     * @param fn - A function that takes the `Ok` value of type `T` and returns a new value of type `U`.
     * @returns A new `Result` containing the transformed value (`Ok<U>`) if the original `Result` is `Ok`, or the same error (`Err<E>`) if the original `Result` is `Err`.
     * @example
     * const result = Ok(5);
     * const mapped = result.map(x => x.toString());
     * // mapped: Result<string, Error> = Ok("5")
     *
     * const error: Result<number, Error> = Err(new Error("Failed"));
     * const mappedError = error.map(x => x.toString());
     * // mappedError: Result<string, Error> = Err(Error("Failed"))
     */
    map<U>(fn: (value: T) => U): Result<U, E>;
    /**
     * Transforms the `Ok` value into a plain value, or returns the provided default when the result is `Err`.
     * The default is evaluated eagerly.
     * @template U - The plain value type returned by either branch.
     * @param {U} defaultValue - Value returned when the result is `Err`.
     * @param {(value: T) => U} fn - Function used to transform the `Ok` value.
     * @returns {U} Either the transformed `Ok` value or `defaultValue`.
     */
    mapOr<U>(defaultValue: U, fn: (value: T) => U): U;
    /**
     * Transforms either branch of the result into a plain value.
     * When the result is `Err`, `defaultFn` receives the error; when it is `Ok`, `fn` receives the success value.
     * @template U - The plain value type returned by either branch.
     * @param {(error: E) => U} defaultFn - Function used to transform the `Err` value.
     * @param {(value: T) => U} fn - Function used to transform the `Ok` value.
     * @returns {U} The value returned by the matching branch transformer.
     */
    mapOrElse<U>(defaultFn: (error: E) => U, fn: (value: T) => U): U;
    /**
     * Transforms the error value of a `Result` using the provided function, preserving the ok value if in the `Ok` state.
     * @template U - The type of the transformed error value.
     * @param fn - A function that takes the `Err` value of type `E` and returns a new error of type `U`.
     * @returns A new `Result` containing the transformed error (`Err<U>`) if the original `Result` is `Err`, or the same value (`Ok<T>`) if the original `Result` is `Ok`.
     * @example
     * const error = ErrFromText("Something happened");
     * const mapped = error.mapErr(e => new AppError(`Error: ${e.message}`));
     * // mapped: Result<undefined, AppError>;
     *
     * const result = Ok(5);
     * const mapped = result.mapErr(e => new AppError(`Error: ${e.message}`));
     * // mapped: Result<number, Error> = Ok("5")
     */
    mapErr<U extends Error>(fn: (error: E) => U): Result<T, U>;
    /**
     * Pattern matches on the Result state, transforming both `Ok` and `Err` cases into a common type.
     *
     * @template U - The type that both transformations will produce.
     * @param {object} matchers - An object containing the transformation functions for `Ok` and `Err` states.
     * @param {(value: T) => U} matchers.okFn - The function to apply if the Result is `Ok`. It receives the `Ok` value.
     * @param {(value: E) => U} matchers.errFn - The function to apply if the Result is `Err`. It receives the `Err` value.
     * @returns {U} The result of either `okFn` or `errFn` depending on the Result state.
     *
     * @example
     * const result: Result<number, Error> = Ok(42);
     * const message = result.match({
     * okFn: value => `Success: ${value}`,
     * errFn: error => `Error: ${error.message}`
     * }); // "Success: 42"
     *
     * const error: Result<number> = Err(new Error("Failed"));
     * const errorMessage = error.match({
     * okFn: value => `Success: ${value}`,
     * errFn: error => `Error: ${error.message}`
     * }); // "Error: Failed"
     */
    match<U>(matchers: {
        okFn: (value: T) => U;
        errFn: ((error: E) => U) | (() => U);
    }): U;
    /**
     * Returns this result if it is `Ok`, otherwise returns the provided fallback `Result`.
     * This is the eager counterpart to `orElse`.
     * @template F - The error type of the fallback result.
     * @param {Result<T, F>} result - Fallback result used when this value is `Err`.
     * @returns {Result<T, F>} The current success value when `Ok`, or the provided fallback result when `Err`.
     */
    or<F extends Error>(result: Result<T, F>): Result<T, F>;
    /**
     * Recovers from an `Err` by calling a function that returns a new `Result`.
     * If this result is `Ok`, the original success value is preserved.
     * @template F - The error type of the recovery result.
     * @param {(error: E) => Result<T, F>} fn - Function called with the current error when the result is `Err`.
     * @returns {Result<T, F>} The recovery result when `Err`, or the current success value when `Ok`.
     */
    orElse<F extends Error>(fn: (error: E) => Result<T, F>): Result<T, F>;
    /**
     * Extracts the value from an `OkState<T>` result or throws the error from an `ErrorState<E>` result.
     * @returns The success value (`T`) if `OkState<T>`, or throws the error (`E`) if `ErrorState<E>`.
     * @throws {E} The error if the result is in the Error state.
     */
    unwrap(): T;
    /**
     * Extracts the error from an `Err` result.
     * @returns {E} The contained error.
     * @throws {Error} Throws when the result is `Ok`.
     */
    unwrapErr(): E;
    /**
     * Returns the success value if the Result is `Ok`, or computes a fallback value from the error if it's `Err`.
     * Unlike `unwrapOr`, the fallback is lazy and receives the original error.
     * @param {(error: E) => T} fn - Function to handle the error case and provide a fallback value.
     * @returns {T} Either the success value or the value returned by the error handler.
     * @example
     * const result: Result<number, Error> = Ok(42);
     * const value = result.unwrapOrElse(() => 0); // 42
     *
     * const error: Result<number, Error> = Err(new Error("Failed"));
     * const fallback = error.unwrapOrElse(err => err.message.length); // 6
     */
    unwrapOrElse(fn: (error: E) => T): T;
    /**
     * Returns the success value if the Result is `Ok`, or the fallback value if it's `Err`.
     * @template T - The type of the ok and the fallback value.
     * @param {T} fallback - Fallback value to return if the result is `ErrorState`.
     * @returns {T} Either the success value or the fallback value.
     * @example
     * const result: Result<number, Error> = Ok(42);
     * const value = result.unwrapOr(0); // 42
     *
     * const error: Result<number, Error> = Err(new Error("Failed"));
     * const fallback = error.unwrapOr(0); // 0
     */
    unwrapOr(fallback: T): T;
}
/**
 * Represents a successful result state with an `ok` value and no error (undefined).
 * @template T - The type of the success value.
 * @template E - The error type, must extend `Error` (defaults to `Error`).
 */
interface OkState<T, E extends Error = Error> extends ResultMethods<T, E> {
    /** The success value of type `T`. */
    readonly ok: T;
    /** Always `undefined` in the `Ok` state, indicating no error. */
    readonly error: undefined;
}
/**
 * Represents an error result state with an error of type `E` and no value (undefined).
 * @template E - The error type, must extend `Error`.
 * @template T - The type of the success value (used for type compatibility with `Result`).
 */
interface ErrorState<E extends Error = Error, T = undefined> extends ResultMethods<T, E> {
    /** Always `undefined` in the `Error` state, indicating no value. */
    readonly ok: undefined;
    /** The error of type `E`. */
    readonly error: E;
}
/**
 * Simulates Rust's `Result` enum, representing either a success (`Ok`) or failure (`Err`).
 * @template T - The type of the success value.
 * @template E - The error type, must extend `Error` (defaults to `Error`).
 * @remarks A `Result` is either an `OkState` with a value (`ok: T`, `error: undefined`)
 * or an `ErrorState` with an error (`ok: undefined`, `error: E`).
 * Use `isOk()` and `isError()` for type-safe checking, and `unwrap()` to extract the value or throw the error.
 */
type Result<T, E extends Error = Error> = OkState<T, E> | ErrorState<E, T>;
/**
 * Represents a custom error type that extends the built-in `Error` object
 * with additional properties defined in `CustomErrorProps`.
 *
 * @example
 * const err: CustomError<{ code: number; info: string }> =
 *   Object.assign(new Error("Oops"), { code: 404, info: "Not Found" });
 * console.log(err.info); // "Not Found"
 * console.log(err.code); // 404
 */
type CustomError<T extends OptionalKeyValue = undefined> = T extends undefined ? Error : Error & CustomErrorProps<T>;
/**
 * Defines the shape of properties that can be added to a custom error.
 * When `T` is `undefined`, resolves to `never`. Otherwise, it combines `T` with optional
 * standard error properties.
 * @template T - The type of additional properties to include in the error.
 * @example
 * type ApiErrorProps = CustomErrorProps<{ code: number; status: string }>;
 * // Equivalent to: { code: number; status: string; message?: string; cause?: unknown }
 */
type CustomErrorProps<T extends OptionalKeyValue> = T extends undefined ? never : T & (T extends {
    message: string;
} ? {} : {
    message?: string;
}) & (T extends {
    cause: any;
} ? {} : {
    cause?: unknown;
});
/**
 * A function type that takes a tuple of arguments and returns a value.
 * @template Args - A tuple type representing the arguments the function accepts.
 * @template T - The return type of the function.
 * @example
 * // A function that takes two numbers and returns a number
 * type Add = Callback<[number, number], number>;
 *
 * // A function that takes no arguments and returns a string
 * type GetText = Callback<[], string>;
 */
type Callback<Args extends unknown[], T> = (...args: Args) => T;
/**
 * Represents an object that can have any string or symbol keys with unknown value types.
 * Useful for type-checking objects with dynamic property access.
 * @example
 * const config: KeyValue = {
 *   timeout: 1000,
 *   retry: true,
 *   onError: (err: Error) => {}
 * };
 */
type KeyValue = Record<string | symbol, unknown>;
/**
 * A variant of KeyValue that can also be undefined.
 * Useful for optional configuration objects or function parameters.
 * @example
 * function configure(options?: OptionalKeyValue) {
 *   // options might be undefined
 *   const timeout = options?.timeout; // unknown
 * }
 */
type OptionalKeyValue = KeyValue | undefined;

/**
 * Wraps a synchronous function, capturing its return value as an `Ok` result or any thrown error as an `Error` result.
 * @template T - The type of the success value returned by the callback.
 * @param callback - A synchronous function that may return a value or throw an error.
 * @returns {Result<T, CustomError>} A `Result` containing the function's return value (`Ok`) or the caught error (`Error`).
 * @example
 * function divide(a: number, b: number): number {
 *   if (b === 0) throw new Error("Division by zero");
 *   return a / b;
 * }
 * const result = wrap(() => divide(10, 2)); // { ok: 5, error: undefined }
 * const errorResult = wrap(() => divide(10, 0)); // { ok: undefined, error: Error("Division by zero") }
 */
declare function wrap<T>(callback: () => T): Result<T, CustomError>;
/**
 * Wraps an asynchronous function, capturing its resolved value as an `Ok` result or any rejected error as an `Error` result.
 * @template T - The type of the success value resolved by the callback's promise.
 * @param callback - An asynchronous function that returns a `Promise` which may resolve to a value or reject with an error.
 * @returns {Promise<Result<T, CustomError>>} A `Promise` resolving to a `Result` containing the resolved value (`Ok`) or the caught error (`Error`).
 * @example
 * async function divideAsync(a: number, b: number): Promise<number> {
 *   if (b === 0) throw new Error("Division by zero");
 *   return a / b;
 * }
 * const result = await wrapAsync(async () => await divideAsync(10, 2)); // { ok: 5, error: undefined }
 * const errRes = await wrapAsync(async () => await divideAsync(10, 0)); // { ok: undefined, error: Error("Division by zero") }
 */
declare function wrapAsync<T>(callback: () => Promise<T>): Promise<Result<T, CustomError>>;
/**
 * Wraps a function that might throw errors into a function that returns a Result type.
 * @template Args - The tuple type of arguments the function accepts
 * @template T - The type of value the function returns
 * @param callback - The function to wrap, which may throw errors
 * @returns A new function that takes the same arguments but returns a Result type
 * @example
 * const divide = (a: number, b: number): number => {
 *   if (b === 0) throw new Error("Division by zero");
 *   return a / b;
 * };
 * const safeDivide = wrapThrowable(divide);
 * const result = safeDivide(10, 2); // { ok: 5, error: undefined }
 * const errorResult = safeDivide(10, 0); // { ok: undefined, error: Error("Division by zero") }
 */
declare function wrapThrowable<T, Args extends unknown[] = []>(callback: Callback<Args, T>): Callback<Args, Result<T, CustomError>>;
/**
 * Wraps an async function that might throw errors into a function that returns a Promise of Result type.
 * @template Args - The tuple type of arguments the function accepts
 * @template T - The type of value the function's Promise resolves to
 * @param callback - The async function to wrap, which may throw errors or reject its Promise
 * @returns A new async function that takes the same arguments but returns a Promise of Result type
 * @example
 * const fetchJson = wrapAsyncThrowable(async (url: string) => {
 *   const res = await fetch(url);
 *   if (!res.ok) throw new Error("Failed to fetch");
 *   return res.json();
 * });
 *
 * const result = await fetchJson("https://example.com/data.json");
 * if (result.isOk()) {
 *   console.log(result.ok);
 * } else {
 *   console.error(result.error.message);
 * }
 */
declare function wrapAsyncThrowable<T, Args extends unknown[] = []>(callback: Callback<Args, Promise<T>>): Callback<Args, Promise<Result<T, CustomError>>>;

/**
 * Creates a successful `Result` in the `Ok` state.
 * @template T - The type of the success value.
 * @template E - The error type, must extend `Error` (defaults to `Error`).
 * @param {T} ok - The success value
 * @returns {OkState<T, E>} A `Result` in the `Ok` state.
 * @example
 * const result = Ok(42);
 * // result: { ok: 42, error: undefined } // and some helper methods
 */
declare function Ok<T, E extends Error = Error>(ok: T): OkState<T, E>;
/**
 * Creates a failure `Result` in the `Error` state from an `Error` instance.
 * @template E - The error type, must extend `Error`.
 * @template T - The type of the success value (used for type compatibility with `Result`).
 * @param {E} error - The error instance, must be an instance of `Error` or a subclass.
 * @returns {ErrorState<E, T>} A `Result` in the `Error` state with the provided error and no value.
 * @throws {TypeError} If the provided `error` is not an instance of `Error`.
 * @example
 * const result = Err(new Error("Something went wrong"));
 * // result: { ok: undefined, error: Error("Something went wrong") } // and some helper methods
 */
declare function Err<T = undefined, E extends Error = Error>(error: E): ErrorState<E, T>;
/**
 * Creates a failure `Result` in the `Error` state from an `unknown` variable.
 * @template T - The type of the success value (used for type compatibility with `Result`).
 * @param {unknown} error - The unknown error from catch statement.
 * @returns {ErrorState<CustomError, T>} A `Result` in the `ErrorState` with the provided error and no value.
 * @example
 * function mayThrow() {
 *   try {
 *     throw new Error("Something went wrong")
 *   } catch (e) {
 *     return ErrFromUnknown(e);
 *   };
 * }
 * const result = mayThrow();
 * // result: { ok: undefined, error: Error("Something went wrong") } // and some helper methods
 */
declare function ErrFromUnknown<T = undefined>(error: unknown): ErrorState<CustomError, T>;
declare function ErrFromText<T = undefined>(message: string): ErrorState<Error, T>;
/**
 * Creates a failure `Result` in the `Error` state from custom error properties.
 * This is particularly useful for creating type-safe error objects with additional metadata.
 *
 * @template T - The success type parameter (unused in the error case but maintains Result type compatibility)
 * @template P - The type of additional properties for the custom error
 * @param {CustomErrorProps<P>} props - An object containing error properties including an optional message and cause
 * @returns {ErrorState<CustomError<P>, T>} A `Result` in the `Error` state with the provided error properties
 *
 * @example
 * // Basic usage with custom properties
 * const result = ErrFromObject<number, { code: number; status: string }>({
 *   message: 'Resource not found',
 *   code: 404,
 *   status: 'Not Found'
 * });
 *
 * if (result.isError()) {
 *   console.log(result.error.message); // 'Resource not found'
 *   console.log(result.error.code);    // 404
 *   console.log(result.error.status);   // 'Not Found'
 * }
 *
 * // With error cause
 * try {
 *   // Some operation that might throw
 * } catch (cause) {
 *   const result = ErrFromObject({
 *     message: 'Operation failed',
 *     cause,
 *     timestamp: new Date().toISOString()
 *   });
 * }
 */
declare function ErrFromObject<P extends KeyValue = KeyValue, T = undefined>(props: CustomErrorProps<P>): ErrorState<CustomError<P>, T>;

export { type CustomError, Err, ErrFromObject, ErrFromText, ErrFromUnknown, Ok, type Result, wrap, wrapAsync, wrapAsyncThrowable, wrapThrowable };
