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>
}
}