Functions
Useful functions to work with Result
types
ok
Creates an Ok
variant of a Result
containing
the given value.
If called without arguments, narrows the type to Result<void, E>
, which is useful
when you want to represent a successful operation without a value.
const x: Result<void, string> = ok<string>();
const y: Result<number, string> = ok<number, string>(42);
expect(x.isOk()).toBe(true);
expect(x.unwrap()).toBeUndefined();
expect(y.isOk()).toBe(true);
expect(y.unwrap()).toBe(42);
err
Creates an Err
variant of a Result
containing the given error.
If called without arguments, narrows the type to Result<T, void>
, which is useful
when you want to represent a failed operation without a specific error value.
Wraps the provided error in a CheckedError
within an Err
,
indicating a failed outcome for a checked Result
. This function accepts
raw error value or CheckedError
.
const x: Result<number, void> = err<number>();
const y: Result<number, string> = err<number, string>("failure");
expect(x.isErr()).toBe(true);
expect(x.unwrapErr().expected).toBeUndefined();
expect(x.unwrapErr().unexpected).toBeUndefined();
expect(y.isErr()).toBe(true);
expect(y.unwrapErr().expected).toBe("failure");
expect(x.unwrapErr().unexpected).toBeUndefined();
pendingOk
pendingOk<T, E>(value: T | Promise<T>): PendingResult<Awaited<T>, Awaited<E>>
Creates a PendingResult
that
resolves to Ok
containing the Awaited
value.
Takes a value or promise and wraps its resolved result in an Ok
,
ensuring the value type is Awaited
to handle any PromiseLike
input.
const x = pendingOk<number, string>(42);
const y = pendingOk<string, number>(Promise.resolve("hello"));
expect(await x).toStrictEqual(ok(42));
expect(await y).toStrictEqual(ok("hello"));
pendingErr
Creates a PendingResult
that
resolves to Err
containing the Awaited
error.
Takes an error or promise and wraps its resolved result in an Err
,
ensuring the error type is Awaited
to handle any PromiseLike
input.
const x = pendingErr<number, string>("failure");
const y = pendingErr<string, number>(Promise.resolve(42));
expect(await x).toStrictEqual(err("failure"));
expect(await y).toStrictEqual(err(42));
pendingResult
Creates a PendingResult
from a result,
promise, or factory function.
Accepts a Result
, a Promise
resolving to a Result
, or
a function returning either, and converts it into a pending result, handling
asynchronous resolution as needed.
const x = pendingResult(ok<number, string>(42));
const y = pendingResult(() => Promise.resolve(err<string, number>(42)));
const z = pendingResult(async () => err<string, boolean>(true));
expect(await x).toStrictEqual(ok(42));
expect(await y).toStrictEqual(err(42));
expect(await z).toStrictEqual(err(true));
run
run<T, E>(action: () => Awaited<T>, mkErr: (error: unknown) => Awaited<E>): Result<T, E>
Executes a synchronous action and wraps the outcome in a
Result
,
handling errors with a custom error mapper.
The run
function attempts to execute the provided action
function,
which returns a value of type T
. If the action succeeds, it returns an
Ok
variant containing the result. If the action fails (throws an error),
the error is passed to the mkErr
function to create an error of type E
,
which is then wrapped in an Err
variant.
This function is useful for safely executing operations that might fail,
ensuring errors are handled in a type-safe way using the Result
type.
const result: Result<{ key: string }, Error> = run(
(): { key: string } => JSON.parse('{ key: "value" }'),
(e) => new Error(`Operation failed: ${JSON.stringify(e)}`),
);
if (result.isOk()) {
console.log(result.unwrap()); // { key: "value" }
}
runAsync
runAsync<T, E>(action: () => Promise<T>, mkErr: (error: unknown) => Awaited<E>): PendingResult<T, E>
Executes an asynchronous action and wraps the outcome in a
PendingResult
,
handling errors with a custom error mapper.
The runAsync
function attempts to execute the provided action
function,
which returns a value of type Promise<T>
. If the action succeeds, it returns a
PendingResult
that resolves to Ok
variant containing the value.
If the action fails (throws an error or rejects), the error is passed to the mkErr
function to create an error of type E
, which is then wrapped in an Err
variant.
This function is useful for safely executing operations that might fail,
ensuring errors are handled in a type-safe way using the PendingResult
type.
const pendingRes: PendingResult<string, Error> = runAsync(
(): Promise<string> => fetch("https://api.example.com/text").then((res) => res.text()),
(e) => new Error(`Fetch failed: ${JSON.stringify(e)}`),
);
const res: Result<string, Error> = await pendingRes;
if (res.isErr()) {
console.log(res.unwrapErr().message); // Fetch failed: ...
}
runResult
runResult<T, E>(getResult: () => Result<T, E>): Result<T, E>
Safely executes an action that returns a Result
, capturing thrown
synchronous errors as an Err
variant.
The runResult
function executes the provided getResult
function,
which returns a Result<T, E>
. If the action succeeds, it returns the Result
as-is (either Ok<T>
or Err<E>
). If the action throws an error, it is
captured and wrapped in an Err
variant returning
UnexpectedError
with a
ResultErrorKind.Unexpected
kind.
This function is useful for safely running synchronous Result
-producing actions,
if you are not 100% sure that the action will not throw an error, ensuring that any
thrown errors are converted into an Err
variant in a type-safe way.
// Successful Result
const success = runResult(() => ok(42));
console.log(success.unwrap()); // 42
// Failed Result
const failure = runResult(() => err(new Error("Already failed")));
// "Expected error occurred: Error: Already failed"
console.log(failure.unwrapErr().expected?.message);
// Action throws an error
const thrown = runResult(() => {
throw new Error("Oops");
});
// "Unexpected error occurred: ResultError: [Unexpected] `runResult`: result action threw an exception. Reason: Error: Oops"
console.log(thrown.unwrapErr().unexpected?.message);
runPendingResult
runPendingResult<T, E>(getResult: () => PendingResult<T, E>): PendingResult<T, E>
Safely executes an action that returns a PendingResult
, capturing
thrown synchronous errors as an Err
variant.
The runPendingResult
function executes the provided getResult
function, which returns a PendingResult<T, E>
. If the action succeeds, it
returns the PendingResult
as-is. If the action throws an error synchronously,
the error is captured and wrapped in a resolved Err
variant returning
UnexpectedError
with a
ResultErrorKind.Unexpected
kind.
This overload is useful for safely running asynchronous PendingResult
-producing actions,
if you are not 100% sure that the action will not throw an error, ensuring that any
synchronous errors are converted into an Err
variant in a type-safe way.
// Successful Result
const success = await runPendingResult(() => pendingOk(42));
console.log(success.unwrap()); // 42
// Failed Result
const failure = await runPendingResult(() =>
pendingErr(new Error("Already failed")),
);
// "Expected error occurred: Error: Already failed"
console.log(failure.unwrapErr().expected?.message);
// Action throws an error
const thrown = await runPendingResult(() => {
throw new Error("Oops");
});
// "Unexpected error occurred: ResultError: [Unexpected] `runPendingResult`: result action threw an exception. Reason: Error: Oops"
console.log(thrown.unwrapErr().unexpected?.message);
isResult
isResult(x: unknown): x is Result<unknown, unknown>
Checks if a value is a Result
,
narrowing its type to Result<unknown, unknown>
.
This type guard verifies whether the input conforms to the Result
interface, indicating it is either an Ok
or Err
.
const x: unknown = ok<number, string>(42);
const y: unknown = err<number, string>("failure");
const z: unknown = "not a result";
expect(isResult(x)).toBe(true);
expect(isResult(y)).toBe(true);
expect(isResult(z)).toBe(false);
if (isResult(x)) {
expect(x.isOk()).toBe(true); // Type narrowed to Result<unknown, unknown>
}
isPendingResult
isPendingResult(x: unknown): x is PendingResult<unknown, unknown>
Checks if a value is a PendingResult
,
narrowing its type to PendingResult<unknown, unknown>
.
This type guard verifies whether the input is a PendingResult
,
indicating it wraps a Promise
resolving to a Result
(either Ok
or Err
).
const x: unknown = pendingResult(ok<number, string>(42));
const y: unknown = pendingResult(err<number, string>("failure"));
const z: unknown = ok(42); // Not a PendingResult
expect(isPendingResult(x)).toBe(true);
expect(isPendingResult(y)).toBe(true);
expect(isPendingResult(z)).toBe(false);
if (isPendingResult(x)) {
// Type narrowed to PendingResult<unknown, unknown>
expect(await x).toStrictEqual(ok(42));
}
isResultError
isResultError(e: unknown): e is ResultError
Checks if a value is a ResultError
, narrowing its type if true.
try {
const x = err("failed")
x.expect("x is err")
} catch (e) {
if (isResultError(e)) {
console.log(e.kind); // type narrowed to ResultError
}
}
isCheckedError
isCheckedError(e: unknown): e is CheckedError<unknown>
Checks if a value is a CheckedError
, narrowing its type if true.
try {
const x: Result<string, Error> = getResultFromSomeWhere();
x.expect("x is err");
} catch (e) {
if (isCheckedError(e)) {
console.log(e.expected); // type narrowed to CheckedError<unknown>
}
}