tryless
Version:
Type-safe error handling for TypeScript without try-catch hell
1,014 lines (1,007 loc) • 34.7 kB
TypeScript
/**
* Constant representing an unknown error type.
* Used as the default error value when no specific error is provided.
*
* @example
* ```ts
* import { UnknownError, err } from 'tryless';
* const failure = err(UnknownError);
* // { success: false, error: 'unknown' }
* ```
*/
declare const UnknownError: "unknown";
/**
* Constant representing an unwrap error type.
* Used internally when unwrap operations fail.
*
* @example
* ```ts
* import { UnwrapErrorName } from 'tryless';
* // Used internally by UnwrapError class
* ```
*/
declare const UnwrapErrorName: "unwrap";
/**
* Abstract base class for result types (Ok and Err).
* Provides a common interface for success and error results with type-safe operations.
*
* @template T - Boolean literal type indicating success (true) or failure (false)
*/
declare abstract class Result<T extends true | false> {
success: T;
constructor(success: T);
/**
* Unwraps the result, returning the data if successful, or throwing if failed.
*
* @param customError - Optional custom error message
* @returns The data contained in a success result
* @throws {UnwrapError} If the result is an error
*/
abstract unwrap(customError?: string): this extends {
data: infer U;
} ? U : never;
/**
* Returns the data if successful, or a default value if failed.
*
* @template U - Type of the default value
* @param defaultValue - Value to return if result is an error
* @returns The data or the default value
*/
abstract unwrapOr<U>(defaultValue: U): this extends {
data: infer J;
} ? J : U;
/**
* Returns the data if successful, or computes a default value from a function if failed.
*
* @template U - Type of the computed default value
* @param defaultValue - Function that computes the default value from the error result
* @returns The data or the computed default value
*/
abstract unwrapOrElse<U>(defaultValue: (result: this extends {
success: false;
} ? this : never) => U): this extends {
data: infer J;
} ? J : U;
/**
* Unwraps an error result, returning it if it's an error, or throwing if it's a success.
*
* @param customError - Optional custom error message
* @returns The error result
* @throws {UnwrapError} If the result is a success
*/
abstract unwrapErr(customError?: string): this extends {
error: string;
} ? this : never;
/**
* Returns the error result if failed, or a default value if successful.
*
* @template U - Type of the default value
* @param defaultValue - Value to return if result is a success
* @returns The error result or the default value
*/
abstract unwrapErrOr<U>(defaultValue: U): this extends {
error: string;
} ? this : U;
/**
* Returns the error result if failed, or computes a default value from a function if successful.
*
* @template U - Type of the computed default value
* @param defaultValue - Function that computes the default value from the success result
* @returns The error result or the computed default value
*/
abstract unwrapErrOrElse<U>(defaultValue: (result: this extends {
success: true;
} ? this : never) => U): this extends {
error: string;
} ? this : U;
/**
* Asserts that the result has a specific error type.
* Returns the result if it matches, throws otherwise.
*
* @template E - Expected error string literal type
* @param error - Expected error string
* @param customError - Optional custom error message
* @returns The result if error matches
* @throws {UnwrapError} If error doesn't match or result is successful
*/
abstract expect<E extends string>(error: E, customError?: string): this extends {
error: E;
} ? this : never;
/**
* Returns the given result if this is successful, otherwise returns this error.
* Logical AND operation for results.
*
* @template R - Type of the result to return
* @param result - Result to return if this is successful
* @returns The given result or this error
*/
abstract and<R extends IUnknownOkErr>(result: R): this extends {
success: true;
} ? R : this;
/**
* Applies a function to the data if successful, otherwise returns this error.
* Allows chaining operations on successful results.
*
* @template U - Type of result returned by the function
* @param fn - Function to apply to the data
* @returns Result from the function or this error
*/
abstract andThen<U extends IUnknownOkErr>(fn: (data: this extends {
data: infer J;
} ? J : never) => U): this extends {
data: unknown;
} ? U : this;
/**
* Returns this result if successful, otherwise returns the given result.
* Logical OR operation for results.
*
* @template R - Type of the fallback result
* @param result - Result to return if this is an error
* @returns This result or the given result
*/
abstract or<R extends IUnknownOkErr>(result: R): this extends {
success: false;
} ? R : this;
/**
* Returns this result if successful, otherwise applies a function to the error.
* Allows recovering from errors.
*
* @template R - Type of result returned by the function
* @param fn - Function to apply to the error
* @returns This result or result from the function
*/
abstract orElse<R extends IUnknownErr>(fn: (errorResult: this extends {
error: infer J;
} ? J : never) => R): this extends {
error: string;
} ? R : this;
/**
* Applies a transformation function to this result.
*
* @template U - Return type of the transformation function
* @param fn - Function to transform the result
* @returns The transformed value
*/
abstract map<U>(fn: (result: this) => U): U;
/**
* Checks if this result represents a success.
*
* @returns True if successful, false otherwise
*/
isOk(): this extends {
success: true;
} ? true : false;
/**
* Checks if this result represents an error.
*
* @returns True if error, false otherwise
*/
isErr(): this extends {
success: false;
} ? true : false;
/**
* Converts the result to a string representation.
*
* @returns String representation of the result
*/
abstract toString(): string;
}
/**
* Represents a successful result containing data.
* This is returned by operations that complete successfully.
*
* @template T - Type of the data contained in the success result
*
* @example
* ```ts
* import { ok } from 'tryless';
* const result = ok(42);
* // result.success === true
* // result.data === 42
* ```
*/
declare class Ok<T = undefined> extends Result<true> {
data: T;
/**
* Creates a new Ok instance.
*
* @param data - The data to wrap in the success result
*/
constructor(data: T);
/**
* Returns the wrapped data.
* This operation is safe because Ok always contains data.
*
* @returns The data contained in this result
*/
unwrap(): this extends {
data: infer J;
} ? J : never;
/**
* Returns the wrapped data.
* The default value is ignored for Ok results.
*
* @template U - Type of the default value (unused)
* @returns The data contained in this result
*/
unwrapOr<U>(_defaultValue: U): this extends {
data: infer J;
} ? J : U;
/**
* Returns the wrapped data.
* The default value function is not called for Ok results.
*
* @template U - Type of the computed value (unused)
* @returns The data contained in this result
*/
unwrapOrElse<U>(_defaultValue: (result: this extends {
success: false;
} ? this : never) => U): this extends {
data: infer J;
} ? J : U;
/**
* Attempts to unwrap as an error, but always throws because this is a success result.
*
* @param customError - Optional custom error message
* @throws {UnwrapError} Always throws because Ok is not an error
*/
unwrapErr(customError?: string): this extends {
error: string;
} ? this : never;
/**
* Returns the default value because this is not an error result.
*
* @template U - Type of the default value
* @param defaultValue - Value to return
* @returns The default value
*/
unwrapErrOr<U>(defaultValue: U): this extends {
error: string;
} ? this : U;
/**
* Computes and returns a default value because this is not an error result.
*
* @template U - Type of the computed value
* @param defaultValue - Function to compute the default value
* @returns The computed default value
*/
unwrapErrOrElse<U>(defaultValue: (result: this extends {
success: true;
} ? this : never) => U): this extends {
error: string;
} ? this : U;
/**
* Asserts that this result is an error with a specific type.
* Always throws because Ok is a success result.
*
* @template E - Expected error type
* @param error - Expected error string
* @param customError - Optional custom error message
* @throws {UnwrapError} Always throws because Ok is not an error
*/
expect<E extends string>(error: E, customError?: string): this extends {
error: E;
} ? this : never;
/**
* Returns the given result because this is a success.
* Implements the logical AND operation.
*
* @template R - Type of the result to return
* @param result - Result to return
* @returns The given result
*/
and<R extends IUnknownOkErr>(result: R): this extends {
success: true;
} ? R : this;
/**
* Applies the function to the wrapped data.
* Enables chaining of operations on successful results.
*
* @template U - Type of result returned by the function
* @param fn - Function to apply to the data
* @returns Result from the function
*/
andThen<U extends IUnknownOkErr>(fn: (data: this extends {
data: infer J;
} ? J : never) => U): this extends {
data: unknown;
} ? U : this;
/**
* Returns this result because it's already successful.
* The alternative result is ignored.
*
* @template R - Type of the alternative result (unused)
* @returns This result
*/
or<R extends IUnknownOkErr>(_result: R): this extends {
success: false;
} ? R : this;
/**
* Returns this result because it's already successful.
* The recovery function is not called.
*
* @template R - Type of result from recovery (unused)
* @returns This result
*/
orElse<R extends IUnknownErr>(_fn: (errorResult: this extends {
error: infer J;
} ? J : never) => R): this extends {
error: string;
} ? R : this;
/**
* Applies a transformation function to this result.
*
* @template U - Return type of the transformation
* @param fn - Function to transform the result
* @returns The transformed value
*/
map<U>(fn: (result: this) => U): U;
/**
* Returns a string representation of this success result.
*
* @returns String in format "Success<data>"
*/
toString(): string;
}
/**
* Represents a failed result containing an error and optional reason.
* This is returned by operations that fail or encounter errors.
*
* @template E - String literal type representing the error identifier
* @template R - Type of the reason/additional error information
*
* @example
* ```ts
* import { err } from 'tryless';
* const result = err('NotFound', 'User not found');
* // result.success === false
* // result.error === 'NotFound'
* // result.reason === 'User not found'
* ```
*/
declare class Err<E extends string, R = undefined> extends Result<false> {
error: E;
reason: R;
stack?: string;
/**
* Creates a new Err instance.
* Automatically captures a stack trace if available.
*
* @param error - The error identifier string
* @param reason - Additional information about the error
* @param caller - Optional function to exclude from stack trace
*/
constructor(error: E, reason: R, caller?: (...args: unknown[]) => unknown);
/**
* Attempts to unwrap the result, but always throws because this is an error.
*
* @param customError - Optional custom error message
* @throws {UnwrapError} Always throws because Err contains no data
*/
unwrap(customError?: string): this extends {
data: infer U;
} ? U : never;
/**
* Returns the default value because this is an error result.
*
* @template U - Type of the default value
* @param defaultValue - Value to return
* @returns The default value
*/
unwrapOr<U>(defaultValue: U): this extends {
data: infer J;
} ? J : U;
/**
* Computes and returns a default value using this error result.
*
* @template U - Type of the computed value
* @param defaultValue - Function to compute the default value from this error
* @returns The computed default value
*/
unwrapOrElse<U>(defaultValue: (result: this extends {
success: false;
} ? this : never) => U): this extends {
data: infer J;
} ? J : U;
/**
* Returns this error result.
* This operation is safe because Err always contains an error.
*
* @returns This error result
*/
unwrapErr(): this extends {
error: string;
} ? this : never;
/**
* Returns this error result.
* The default value is ignored for Err results.
*
* @template U - Type of the default value (unused)
* @returns This error result
*/
unwrapErrOr<U>(_defaultValue: U): this extends {
error: string;
} ? this : U;
/**
* Returns this error result.
* The default value function is not called for Err results.
*
* @template U - Type of the computed value (unused)
* @returns This error result
*/
unwrapErrOrElse<U>(_defaultValue: (result: this extends {
success: true;
} ? this : never) => U): this extends {
error: string;
} ? this : U;
/**
* Asserts that this error matches the expected error type.
* Returns this result if it matches, throws otherwise.
*
* @template U - Expected error string literal type
* @param error - Expected error string
* @param customError - Optional custom error message
* @returns This result if error matches
* @throws {UnwrapError} If error doesn't match
*/
expect<U extends string>(error: U, customError?: string): this extends {
error: U;
} ? this : never;
/**
* Returns this error because it's not a success.
* The alternative result is ignored.
*
* @template R - Type of the alternative result (unused)
* @returns This error result
*/
and<R extends IUnknownOkErr>(_result: R): this extends {
success: true;
} ? R : this;
/**
* Returns this error because it's not a success.
* The function is not called.
*
* @template U - Type of result from function (unused)
* @returns This error result
*/
andThen<U extends IUnknownOkErr>(_fn: (data: this extends {
data: infer J;
} ? J : never) => U): this extends {
data: unknown;
} ? U : this;
/**
* Returns the given result because this is an error.
* Implements the logical OR operation for error recovery.
*
* @template R - Type of the fallback result
* @param result - Result to return as fallback
* @returns The given fallback result
*/
or<R extends IUnknownOkErr>(result: R): this extends {
success: false;
} ? R : this;
/**
* Applies the function to this error for recovery.
* Enables error handling and recovery patterns.
*
* @template R - Type of result returned by the function
* @param fn - Function to handle the error
* @returns Result from the recovery function
*/
orElse<R extends IUnknownErr>(fn: (errorResult: this extends {
error: infer J;
} ? J : never) => R): this extends {
error: string;
} ? R : this;
/**
* Applies a transformation function to this error result.
*
* @template U - Return type of the transformation
* @param fn - Function to transform the result
* @returns The transformed value
*/
map<U>(fn: (result: this) => U): U;
/**
* Returns a string representation of this error result.
*
* @returns String in format "error: reason - stack"
*/
toString(): string;
}
/**
* Type alias for the {@link UnknownError} constant.
* Represents the string literal type "unknown".
*/
type IUnknownError = typeof UnknownError;
/**
* Type representing a generic success result with unknown data.
* Used internally for type-safe result handling when the data type is not specified.
*
* @property success - Always true for success results
* @property data - The data contained in the success result
*/
type IUnknownOk = {
success: true;
data: unknown;
};
/**
* Type representing a generic error result with unknown reason.
* Used internally for type-safe error handling when the error details are not specified.
*
* @property success - Always false for error results
* @property error - The error identifier string
* @property reason - Additional information about the error
* @property stack - Optional stack trace of where the error was created
*/
type IUnknownErr = {
success: false;
error: string;
reason: unknown;
stack?: string;
};
/**
* Union type representing either a success or error result with unknown types.
* Useful for generic result handling where specific types are not known.
*/
type IUnknownOkErr = IUnknownOk | IUnknownErr;
/**
* Represents a result type that can be either a success (Ok) or an error (Err).
* This type provides type-safe error handling without throwing exceptions.
*
* @template T - The type of the success value wrapped by Ok.
* @template E - The error specification. Can be either:
* - An object mapping error names to their reason types: `{ ErrorName: ReasonType }`
* - A union of Err types: `Err<'ErrorName', ReasonType>`
* - IUnknownErr for generic error handling
*
* When using an object mapping, each key becomes an error name and its value
* becomes the type of the error reason, automatically creating a union of Err types.
*
* @example
* ```ts
* // Using object mapping (recommended for multiple errors)
* type UserResult = IResult<User, {
* NotFound: string;
* InvalidEmail: { email: string };
* Underage: { age: number };
* }>;
* // Equivalent to: Ok<User> | Err<'NotFound', string> | Err<'InvalidEmail', { email: string }> | Err<'Underage', { age: number }>
*
* function getUser(id: string): UserResult {
* if (!exists(id)) return err('NotFound', 'User not found');
* if (!validEmail(user.email)) return err('InvalidEmail', { email: user.email });
* if (user.age < 18) return err('Underage', { age: user.age });
* return ok(user);
* }
* ```
*
* @example
* ```ts
* // Using Err union (useful for single or reusable error types)
* type ParseResult = IResult<number, Err<'ParseError', string>>;
*
* function parseNumber(input: string): ParseResult {
* const num = parseInt(input, 10);
* if (isNaN(num)) return err('ParseError', 'Invalid number format');
* return ok(num);
* }
* ```
*
* @example
* ```ts
* // Using IUnknownErr for generic error handling
* import { resultfy } from 'tryless';
*
* type GenericResult = IResult<Data, IUnknownErr>;
*
* async function fetchData(url: string): Promise<GenericResult> {
* return resultfy(
* fetch(url).then(r => r.json()),
* 'FetchError'
* );
* }
* ```
*/
type IResult<T, E extends IUnknownErr | {
[key: string]: unknown;
}> = Ok<T> | (E extends IUnknownErr ? E : {
[K in keyof E]: Err<K & string, E[K]>;
}[keyof E]);
/**
* Extracts the Ok type from a Result type.
* If the type is not an Ok, returns never.
*
* @template T - The Result type to extract from
*
* @example
* ```ts
* type UserResult = IResult<User, { NotFound: string }>;
* type UserOk = IOkOf<UserResult>;
* // Result: Ok<User>
*
* // Useful for narrowing types in generic functions
* function handleSuccess<T extends IResult<unknown, unknown>>(
* result: IOkOf<T>
* ): IOkDataOf<T> {
* return result.data;
* }
* ```
*/
type IOkOf<T> = T extends Ok<infer U> ? Ok<U> : never;
/**
* Extracts the data type from an Ok type.
* If the type is not an Ok, returns never.
*
* @template T - The Result type to extract data from
*
* @example
* ```ts
* type UserResult = IResult<User, { NotFound: string }>;
* type UserData = IOkDataOf<UserResult>;
* // Result: User
*
* // Useful for extracting success data types
* type ApiResult = IResult<{ id: number; name: string }, IUnknownErr>;
* type ApiData = IOkDataOf<ApiResult>;
* // Result: { id: number; name: string }
*
* // In generic functions
* function unwrapMany<T extends IResult<unknown, unknown>>(
* results: T[]
* ): IOkDataOf<T>[] {
* return results
* .filter(r => r.isOk())
* .map(r => r.data as IOkDataOf<T>);
* }
* ```
*/
type IOkDataOf<T> = T extends Ok<infer U> ? U : never;
/**
* Extracts a specific Err type from a Result's error union by error name.
* If K is provided, only returns the Err type with that specific name.
* If the error name doesn't exist, returns never.
*
* @template E - The error union type
* @template K - Optional error name to filter by (defaults to any string)
*
* @example
* ```ts
* type UserResult = IResult<User, {
* NotFound: string;
* InvalidEmail: { email: string };
* Underage: { age: number };
* }>;
*
* // Extract specific error type
* type NotFoundErr = IErrOf<UserResult, 'NotFound'>;
* // Result: Err<'NotFound', string>
*
* type InvalidEmailErr = IErrOf<UserResult, 'InvalidEmail'>;
* // Result: Err<'InvalidEmail', { email: string }>
*
* // Extract all error types
* type AllErrs = IErrOf<UserResult>;
* // Result: Err<'NotFound', string> | Err<'InvalidEmail', { email: string }> | Err<'Underage', { age: number }>
*
* // Useful for error handling functions
* function handleNotFound(err: IErrOf<UserResult, 'NotFound'>) {
* console.log('User not found:', err.reason);
* }
* ```
*/
type IErrOf<E, K extends string = string> = E extends Err<infer U, infer V> ? U extends K ? Err<U, V> : never : never;
/**
* Extracts the reason type from an Err type.
* If K is provided, only returns the reason type for that specific error name.
*
* @template E - The error union type
* @template K - Optional error name to filter by (defaults to any string)
*
* @example
* ```ts
* type UserResult = IResult<User, {
* NotFound: string;
* InvalidEmail: { email: string };
* Underage: { age: number };
* }>;
*
* // Extract reason type for specific error
* type NotFoundReason = IErrReasonOf<UserResult, 'NotFound'>;
* // Result: string
*
* type InvalidEmailReason = IErrReasonOf<UserResult, 'InvalidEmail'>;
* // Result: { email: string }
*
* type UnderageReason = IErrReasonOf<UserResult, 'Underage'>;
* // Result: { age: number }
*
* // Extract all possible reason types
* type AllReasons = IErrReasonOf<UserResult>;
* // Result: string | { email: string } | { age: number }
*
* // Useful for type-safe error handlers
* function logInvalidEmail(reason: IErrReasonOf<UserResult, 'InvalidEmail'>) {
* console.log(`Invalid email: ${reason.email}`);
* // TypeScript knows reason has an 'email' property
* }
*
* function logUnderage(reason: IErrReasonOf<UserResult, 'Underage'>) {
* console.log(`User is ${reason.age} years old`);
* // TypeScript knows reason has an 'age' property
* }
* ```
*/
type IErrReasonOf<E, K extends string = string> = E extends Err<infer U, infer V> ? U extends K ? V : never : never;
/**
* Creates an empty success result.
* Used when an operation succeeds but returns no data.
*
* @returns An Ok result with undefined data
*
* @example
* ```ts
* import { ok } from 'tryless';
* const result = ok();
* // { success: true, data: undefined }
* ```
*/
declare function ok(): Ok;
/**
* Creates a success result containing data.
* Used to wrap successful operation results.
*
* @template T - Type of the data to wrap
* @param data - The data to wrap in the success result
* @returns An Ok result containing the data
*
* @example
* ```ts
* import { ok } from 'tryless';
* const result = ok(42);
* // { success: true, data: 42 }
*
* const user = { id: 1, name: 'John' };
* const userResult = ok(user);
* // { success: true, data: { id: 1, name: 'John' } }
* ```
*/
declare function ok<T>(data: T): Ok<T>;
/**
* Creates an error result with unknown error type.
* Used when an operation fails without specific error information.
*
* @returns An Err result with 'unknown' error
*
* @example
* ```ts
* import { err } from 'tryless';
* const result = err();
* // { success: false, error: 'unknown', reason: undefined }
* ```
*/
declare function err(): Err<IUnknownError>;
/**
* Creates an error result with a specific error type.
* Used when an operation fails with a known error identifier.
*
* @template E - String literal type for the error identifier
* @param error - The error identifier string
* @returns An Err result with the specified error
*
* @example
* ```ts
* import { err } from 'tryless';
* const result = err('NotFound');
* // { success: false, error: 'NotFound', reason: undefined }
* ```
*/
declare function err<E extends string>(error: E): Err<E>;
/**
* Creates an error result with an error type and reason.
* Used when an operation fails and you want to provide additional context.
*
* @template E - String literal type for the error identifier
* @template C - Type of the reason/additional error information
* @param error - The error identifier string
* @param reason - Additional information about the error
* @returns An Err result with the specified error and reason
*
* @example
* ```ts
* import { err } from 'tryless';
* const result = err('Validation', 'Email is required');
* // { success: false, error: 'Validation', reason: 'Email is required' }
*
* const errorWithObject = err('DatabaseError', { code: 500, message: 'Connection failed' });
* // { success: false, error: 'DatabaseError', reason: { code: 500, message: 'Connection failed' } }
* ```
*/
declare function err<E extends string, C>(error: E, reason: C): Err<E, C>;
/**
* Error thrown when attempting to unwrap a Result that contains an error,
* or when expecting a specific error type that doesn't match.
*
* This error provides detailed stack traces showing both where the unwrap
* was attempted and where the original error result was created.
*
* @example
* ```ts
* import { err } from 'tryless';
*
* const result = err('NotFound', 'User not found');
* try {
* const data = result.unwrap(); // throws UnwrapError
* } catch (error) {
* console.log(error.name); // 'UnwrapError'
* console.log(error.error); // 'NotFound'
* console.log(error.reason); // 'User not found'
* }
* ```
*/
declare class UnwrapError extends Error {
/**
* The error identifier from the failed result.
*/
error: string;
/**
* Additional information about why the error occurred.
*/
reason?: unknown;
resultStack?: string;
/**
* Creates a new UnwrapError instance.
*
* @param result - The result that failed to unwrap
* @param caller - The function that attempted the unwrap (for stack trace)
* @param customMessage - Optional custom error message
* @param customError - Optional custom error identifier
*/
constructor(result: IUnknownOkErr, caller: (...args: unknown[]) => unknown, customMessage?: string, customError?: string);
}
/**
* Creates a curried function that transforms data and wraps it in a success result.
* Useful for promise chains and function composition.
*
* @template T - Type of the input data
* @template R - Type of the transformed data
* @param map - Function to transform the input data
* @returns A function that takes data, transforms it, and returns an Ok result
*
* @example
* ```ts
* import { okFulfilled } from 'tryless';
*
* // Simple transformation
* const double = okFulfilled((n: number) => n * 2);
* const result = double(5);
* // { success: true, data: 10 }
*
* // Use in promise chains
* fetch('https://api.example.com/user')
* .then(res => res.json())
* .then(okFulfilled(user => user.name))
* .then(result => {
* if (result.success) {
* console.log(result.data); // user name
* }
* });
* ```
*/
declare function okFulfilled<T, R = T>(map: (data: T) => R): (data: T) => Ok<R>;
/**
* Creates a curried error factory that wraps rejection reasons in error results.
* Particularly useful for converting promise rejections in complex chains.
*
* **Note:** For simple promise wrapping, prefer `resultfy()` which is more concise.
*
* @template E - String literal type for the error identifier
* @param error - The error identifier to use for all rejections
* @returns A function that takes a reason and returns an Err result
*
* @example
* ```ts
* import { errReject, ok, resultfy } from 'tryless';
*
* // Basic usage
* const onReject = errReject('FetchError');
* const result = onReject('Network down');
* // { success: false, error: 'FetchError', reason: 'Network down' }
*
* // Use in complex promise chains
* const userResult = await fetch('https://api.example.com/user')
* .then(ok, errReject('user:fetch-error'))
* .then(res => res.success ? res.data.json() : res)
* .then(ok, errReject('user:parse-error'));
*
* // For simpler cases, prefer resultfy:
* const userResult = await resultfy(
* fetch('https://api.example.com/user'),
* 'user:fetch-error'
* );
* ```
*/
declare function errReject<E extends string>(error: E): (reason: unknown) => Err<E, unknown>;
/**
* Wraps a function or promise to always return a result instead of throwing.
* Converts both synchronous throws and promise rejections into error results.
*
* **Recommended approach** for wrapping promises and functions. More concise than `.then(ok, errReject())`.
*
* **For Promises:** Wraps a promise to return Ok on fulfillment or Err on rejection.
*
* **For Functions:** Returns a wrapped version that catches errors and returns results.
*
* @template F - Type of the function or promise to wrap
* @param fn - The function or promise to wrap
* @param error - Optional custom error identifier (defaults to 'unknown')
* @returns Wrapped version that returns Result types
*
* @example
* ```ts
* import { resultfy } from 'tryless';
*
* // Wrap a promise with custom error message (most common use case)
* const userResult = await resultfy(
* fetch('https://api.example.com/user').then(r => r.json()),
* 'user:fetch-error'
* );
*
* if (userResult.success) {
* console.log(userResult.data); // user data
* } else {
* console.log(userResult.error); // 'user:fetch-error'
* console.log(userResult.reason); // rejection reason
* }
*
* // Wrap a synchronous function
* const divide = (a: number, b: number) => {
* if (b === 0) throw new Error('Division by zero');
* return a / b;
* };
*
* const safeDivide = resultfy(divide, 'division-error');
* const result1 = safeDivide(10, 2);
* // { success: true, data: 5 }
*
* const result2 = safeDivide(10, 0);
* // { success: false, error: 'division-error', reason: Error('Division by zero') }
* ```
*/
/**
* Wraps a promise to return Ok on fulfillment or Err with unknown error on rejection.
*
* @template F - Promise type to wrap
* @param fn - The promise to wrap
* @returns Promise that resolves to Ok or Err result
*/
declare function resultfy<F extends Promise<any>>(fn: F): Promise<Ok<Awaited<F>> | Err<IUnknownError, unknown>>;
/**
* Wraps a promise to return Ok on fulfillment or Err with custom error on rejection.
*
* @template F - Promise type to wrap
* @template E - String literal type for the error identifier
* @param fn - The promise to wrap
* @param error - Custom error identifier to use for rejections
* @returns Promise that resolves to Ok or Err result
*/
declare function resultfy<F extends Promise<any>, E extends string>(fn: F, error: E): Promise<Ok<Awaited<F>> | Err<E, unknown>>;
/**
* Wraps a function to catch errors and return results with unknown error.
*
* @template F - Function type to wrap
* @param fn - The function to wrap
* @returns Wrapped function that returns Result types
*/
declare function resultfy<F extends (...args: any) => any>(fn: F): ReturnType<F> extends never ? (...args: Parameters<F>) => Err<IUnknownError, unknown> : ReturnType<F> extends Promise<never> ? (...args: Parameters<F>) => Promise<Err<IUnknownError, unknown>> : ReturnType<F> extends Promise<infer U> ? (...args: Parameters<F>) => Promise<Ok<U> | Err<IUnknownError, unknown>> : (...args: Parameters<F>) => Ok<ReturnType<F>> | Err<IUnknownError, unknown>;
/**
* Wraps a function to catch errors and return results with custom error.
*
* @template F - Function type to wrap
* @template E - String literal type for the error identifier
* @param fn - The function to wrap
* @param error - Custom error identifier to use for errors
* @returns Wrapped function that returns Result types
*/
declare function resultfy<F extends (...args: any) => any, E extends string>(fn: F, error: E): ReturnType<F> extends never ? (...args: Parameters<F>) => Err<E, unknown> : ReturnType<F> extends Promise<never> ? (...args: Parameters<F>) => Promise<Err<E, unknown>> : ReturnType<F> extends Promise<infer U> ? (...args: Parameters<F>) => Promise<Ok<U> | Err<E, unknown>> : (...args: Parameters<F>) => Ok<ReturnType<F>> | Err<E, unknown>;
export { Err, Ok, Result, UnknownError, UnwrapError, UnwrapErrorName, err, errReject, ok, okFulfilled, resultfy };
export type { IErrOf, IErrReasonOf, IOkDataOf, IOkOf, IResult, IUnknownErr, IUnknownError, IUnknownOk, IUnknownOkErr };