An ergonomic way to work with fallible operations in TypeScript.
API Reference
·
Report Bug
·
Request Feature
·
Road map
- ✨ Fully type-safe, and ergonomic API that uses popular conventions.
- 🎉 Comes with a clean and easy to use way to simulate the do-notation.
- ⚡️ Tree-shakable, works with esm, cjs, and doesn't force you to use
nodenext/node16module resolution.
npm install this-is-ok
yarn add this-is-ok
pnpm add this-is-ok
// an example of adapting a standard library function to use Option
const safeParseInt = (value: string): Option<number> => {
const parsed = parseInt(value);
if (isNaN(parsed)) {
return none;
}
return some(parsed);
};
// `of` from the option module creates an Option from a nullable value
of(localStorage.getItem("counter"))
// map the inner value to another Option
.flatMap((d) => safeParseInt(d))
// map the inner value or use a default value if it's none
.mapOr(0, (d) => d + 1)
// perform any side effect with the value
.tap((d) => localStorage.setItem("counter", d.toString()));Do notation lets us write the "happy path" of a function without having to worry about the error handling.
We access the inner values of options by calling bind on them, and if any point, inside the do block, bind is called on none
then we short-circuit the execution and none is returned.
some(1)
.do((value) => {
const a = some(2).bind();
const b = some("hello").bind();
return some(b.repeat(value + a));
})
.tap(console, log); // "hellohellohello"
some(1).do((value) => {
const a = value; // 1
const b = some(2).bind(); // 2
const c = (none as Option<number>).bind();
// the execution stops here and none is returned
// so the following lines are not executed
const d = some(3).bind();
return some(a + b + c + d);
}).isNone; // true- Option
- Creation
- Methods
isSome: booleanisSomeAnd: (predicate: (value: T) => boolean) => booleanisNone: booleanexpect: (message: string) => Tunwrap: () => TunwrapOr: (defaultValue: T) => TunwrapOrElse: (defaultValueFun: () => T) => Tmap: <U>(f: (value: T) => U) => Option<U>mapOr: <U>(defaultValue: U, f: (value: T) => U) => UmapOrElse: <U>(defaultValueFun: () => U, f: (arg: T) => U) => UokOr: <E>(err: E) => Result<T, E>okOrElse: <E>(f: () => E) => Result<T, E>and: <U>(b: Option<U>) => Option<U>or: (b: Option<T>) => Option<T>orElse: (f: () => Option<T>) => Option<T>flatMap: <U>(f: (value: T) => Option<U>) => Option<U>andThen: <U>(f: (value: T) => Option<U>) => Option<U>tap: <F extends void | Promise<void>>(f: (value: T) => F) => Ffilter: (predicate: (arg: T) => boolean) => Option<T>match: <U>(pattern: { some: (value: T) => U; none: () => U }) => Udo: <U>(f: (value: T) => Option<U>) => Option<U>
- Result
- Creation
- Methods
isOk: booleanisOkAnd: (predicate: (value: T) => boolean) => booleanisErr: booleanisErrAnd: (predicate: (value: E) => boolean) => booleanok: () => Option<T>err: () => Option<T>expect: (message: string) => Tunwrap: () => TexpectErr: (message: string) => TunwrapErr: () => EunwrapOr: (defaultValue: T) => TunwrapOrElse: (defaultValueFun: () => T) => Tmap: <U>(f: (value: T) => U) => Result<U, E>mapOr: <U>(defaultValue: U, f: (value: T) => U) => UmapOrElse: <U>(defaultValueFun: () => U, f: (arg: T) => U) => UmapErr: <U>(f: (value: E) => U) => Result<T, U>and: <U>(b: Result<U, E>) => Result<U, E>or: <F>(b: Result<T, F>) => Result<T,F>orElse: <F>(f: () => Result<T, F>) => Result<T, F>flatMap: <U>(f: (value: T) => Result<U, E>) => Result<U, E>andThen: <U>(f: (value: T) => Result<U, E>) => Result<U, E>do: <U, F>(f: (value: T) => Result<U, F>) => Result<U, F>match: <U>(pattern: { ok: (value: T) => U; err: (value: E) => U }) => U
Converts a nullable value into an option.
Example:
of(1); // some(1)
of(null); // none
of(undefined); // noneCalls a function and converts its result into an option. If the function is null or undefined or it throws an exception, none is returned.
Example:
from(() => 1); // some(1)
from(() => null); // none
from(() => {
throw new Error("oopsie hehe");
}); // noneProperty that is true if the option is a Some variant and false otherwise.
Example:
some(3).isSome; // true
none.isSome; // falseReturns true if the option is a Some variant and the value inside of it matches a predicate.
Example:
expect(some(42).isSomeAnd((v) => v % 2)).toBe(true);
expect(some(42).isSomeAnd((v) => v > 100)).toBe(true);Property that is true if the option is a None variant and false otherwise.
Example:
expect(none.isNone).toBe(true);
expect(some(42).isNone).toBe(false);Returns the inner value. Useful for situations where if the
option is a None then there is no tap to continue running the program.
The message can be used for debugging purposes.
Parameters:
message- The message to throw if the option is aNonevariant.
Throws:
Throws the given message if the option is a None variant.
Example:
expect(some(42).expect("should be a number")).toBe(42);
expect(none.expect("this will throw")).toThrow();Returns the inner value or throws an Error if the option is a None variant.
Throws:
Throws if the option is a None variant.
Example:
expect(some(42).unwrap()).toBe(42);
expect(none.unwrap()).toThrow();Returns the inner value or the provided default value.
Example:
expect(some(42).unwrapOr(1)).toBe(42);
expect(none.unwrapOr(1)).toBe(1);Returns the inner value or computes it from a function.
Example:
expect(some(42).unwrapOrElse(() => 1)).toBe(42);
expect(none.unwrapOrElse(() => 1)).toBe(1);Maps an Option<T> to Option<U> by applying a function to a contained
value (if Some) or returns None (if None).
Example:
expect(
some(42)
.map((x) => x + 1)
.unwrap()
).toBe(43);
expect(none.map((x) => x + 1).isNone()).toBe(true);Returns the provided default result (if none), or applies a function to the contained value (if any).
Example:
expect(
some(42)
.mapOr(10, (x) => x + 1)
.unwrap()
).toBe(43);
expect(none.mapOr(10, (x) => x + 1).unwrap()).toBe(11);Computes a default function result (if none), or applies a different function to the contained value (if any).
Example:
expect(
some(42)
.mapOrElse(
() => 10,
(x) => x + 1
)
.unwrap()
).toBe(43);
expect(
none
.mapOrElse(
() => 10,
(x) => x + 1
)
.unwrap()
).toBe(11);Given an error: E converts Option<T> to Result<T, E>.
Example:
some(42).okOr("error"); // { variant: "ok", value: 42, ... }
none.okOr("error"); // { variant: "error", error: "error", ... }Same as okOr but the error is computed from a function.
Returns None if the option is None, otherwise returns b.
Example:
expect(some(42).and(some(1)).unwrap()).toBe(1);
expect(none.and(some(1)).is
None()).toBe(true);Returns None if the option is None, otherwise returns b.
Example:
expect(some(42).or(some(1)).unwrap()).toBe(43);
expect(none.or(some(1)).unwrap()).toBe(1);Returns the option if it contains a value, otherwise calls f and returns the result.
Example:
expect(
some(42)
.orElse(() => some(1))
.unwrap()
).toBe(42);
expect(none.orElse(() => some(1)).unwrap()).toBe(1);Returns None if the option is None, otherwise calls f with the wrapped value and returns the result.
Example:
expect(
some(42)
.flatMap((x) => some(x + 1))
.unwrap()
).toBe(43);
expect(
some(42)
.flatMap((x) => none)
.isNone()
).toBe(true);Returns None if the option is None, otherwise calls f with the wrapped value and returns the result.
Example:
expect(
some(42)
.andThen((x) => some(x + 1))
.unwrap()
).toBe(43);
expect(
some(42)
.andThen((x) => none)
.isNone()
).toBe(true);Runs the given void function with the inner value if the option is a Some variant
or does nothing if the option is a None variant.
Example:
expect(
some(42)
.tap((x) => some(x + 1))
.unwrap()
).toBe(43);
expect(
some(42)
.tap((x) => none)
.isNone()
).toBe(true);Returns None if the option is None, otherwise returns None if the predicate predicate returns false when applied to the contained
value, otherwise returns the Option<T>.
Example:
expect(
some(42)
.filter((x) => x > 10)
.unwrap()
).toBe(42);
expect(
some(42)
.filter((x) => x < 10)
.isNone()
).toBe(true);Allows you to run different functions depending on the variant of the option.
Example:
expect(
some(3).match({
some: (d) => d + 1,
none: () => 0,
})
).toBe(4);
expect(
none.match({
some: (d) => d + 1,
none: () => 0,
})
).toBe(0);Lets you simulate a do-notation known from functional languages with the Option monad.
Example:
expect(
some(1)
.do((value) => {
const a = value;
const b = some(2).bind();
const c = some(3).bind();
return some(a + b + c);
})
.unwrap()
).toBe(6);Creates a new Result<T, E> from a possibly nullable value and an error.
Example:
expect(of(42, "error").unwrap()).toBe(42);
expect(of({}, "error").unwrap()).toEqual({});
expect(of(NaN, "error").unwrap()).toEqual(NaN);
expect(of("", "error").unwrap()).toEqual("");
expect(of(null, "error").isErr).toBe(true);
expect(of(undefined, "error").isErr).toBe(true);Creates a new Result<T, E> from a function that can throw and an error.
Example:
expect(from(() => 42, "error").unwrap()).toBe(42);
expect(from(() => ({}), "error").unwrap()).toEqual({});
expect(from(() => NaN, "error").unwrap()).toEqual(NaN);
expect(from(() => "", "error").unwrap()).toEqual("");
expect(from(() => null, "error").isErr).toBe(true);
expect(from(() => undefined, "error").isErr).toBe(true);
expect(
from(() => {
throw "error";
}, "error").isErr
).toBe(true);Creates a new Result<T, E> from a function that can throw.
If the function returns any value (including null and undefined) it is wrapped in an Ok variant. If the function throws an error it is wrapped in an Err variant. Errors that are not of type Error are wrapped in an Error object.
Example:
expect(fromThrowable(() => 42).unwrap()).toBe(42);
expect(fromThrowable(() => ({})).unwrap()).toEqual({});
expect(fromThrowable(() => NaN).unwrap()).toEqual(NaN);
expect(fromThrowable(() => "").unwrap()).toEqual("");
expect(fromThrowable(() => null).unwrap()).toEqual(null);
expect(fromThrowable(() => undefined).unwrap()).toEqual(undefined);
const a = fromThrowable(() => {
throw "error";
});
expect(a.unwrapErr()).toEqual(new Error("error"));
const b = fromThrowable(() => {
throw new Error("error");
});
expect(b.unwrapErr()).toEqual(new Error("error"));Property that is true if the result is Ok.
Example:
expect(ok(42).isOk).toBe(true);
expect(err("error").isOk).toBe(false);Returns true if the result is an Ok variant and the value inside of it matches a predicate.
Example:
expect(some(42).isSomeAnd((v) => v % 2)).toBe(true);
expect(some(42).isSomeAnd((v) => v > 100)).toBe(true);Property that is true if the result is Err.
Example:
expect(ok(42).isErr).toBe(false);
expect(err("error").isErr).toBe(true);Returns true if the result is an Err variant and the value inside of it matches a predicate.
Example:
expect(some(42).isSomeAnd((v) => v % 2)).toBe(true);
expect(some(42).isSomeAnd((v) => v > 100)).toBe(true);Converts from Result<T, E> to Option discarding the error, if any.
Example:
expect(ok(42).ok()).toEqual(some(42));
expect(err("error").ok()).toEqual(none);Converts from Result<T, E> to Option discarding the error, if any.
Example:
expect(ok(42).ok()).toEqual(some(42));
expect(err("error").ok()).toEqual(none);Returns the inner value. Useful for situations where if the result is an Err then there is no use to continue running the program. The message can be used for debugging purposes.
message: The message to throw if the option is anErrvariant.
Throws:
- Throws the given message if the option is an
Errvariant.
Example:
expect(ok(42).expect("should be a number")).toBe(42);
expect(err("error").expect("this will throw")).toThrow();Returns the Ok value or throws an Error if the result is an Err variant.
Throws:
- Throws if the option is a
Nonevariant.
Example:
expect(ok(42).unwrap()).toBe(42)
expect(err("error").unwrap().toThrow()Returns the contained Err value or throws an error if the result is an Ok variant.
message: The message to throw if the option is anOkvariant.
Throws:
- Throws the given message if the option is an
Okvariant.
Example:
expect(err(42).expectErr("should be a number")).toBe(42);
expect(ok(42).expectErr("this will throw")).toThrow();Returns the contained Err value or throws an error if the result is an Ok variant.
Throws:
- Throws if the option is a
Nonevariant.
**Example
:**
expect(err("error").unwrapErr()).toBe(42)
expect(ok(42).unwrapErr().toThrow()Returns the Ok value or the provided default value.
defaultValue: The default value to return if the result is anErrvariant.
Example:
expect(ok(42).unwrapOr(1)).toBe(42)
expect(err("error").unwrapOr(1).toBe(1)Returns the Ok value or computes it from a function.
defaultValueFun: The function that computes the default value if the result is anErrvariant.
Example:
expect(ok(42).unwrapOrElse(() => 1)).toBe(42)
expect(err("error").unwrapOrElse(() => 1).toBe(1)Maps a Result<T, E> to Result<U, E> by applying a function to a contained Ok value, leaving an Err value untouched.
Example:
expect(
ok(42)
.map((x) => x + 1)
.unwrap()
).toBe(43);
expect(
err("error")
.map((x) => x + 1)
.isNone()
).toBe(true);Returns the provided default (if Err), or applies a function to the contained value (if Ok).
defaultValue: The default value to return if the result is anErrvariant.f: The function to apply to the contained value if the result is anOkvariant.
Example:
expect(ok(42).mapOr(10, (x) => x + 1)).toBe(43);
expect(error("error").mapOr(10, (x) => x + 1)).toBe(11);Maps a Result<T, E> to U by applying a fallback function default to a contained Err value, or function f to a contained Ok value.
defaultValueFun: The fallback function to apply to the contained Err value.f: The function to apply to the contained Ok value.
Example:
expect(ok(42).mapOrElse(() => 10, (x) => x + 1))).toBe(43)
expect(error("error").mapOrElse(() => 10, (x) => x + 1))).toBe(11)Maps a Result<T, E> to Result<T, F> by applying a function to a contained Err value, leaving an Ok value untouched.
Example:
expect(
ok(42)
.map((x) => x + 1)
.unwrap()
).toBe(43);
expect(
err("error")
.map((x) => x + 1)
.isNone()
).toBe(true);Returns res if the result is Ok, otherwise returns the Err value of self.
b: The Result value to return if the current result is Ok.
Returns res if the result is Err, otherwise returns the Ok value of self.
b: The Result value to return if the current result is Err.
Returns the option if it contains a value, otherwise calls f and returns the result.
f: The function to call if the result is anErrvariant.
Returns err if the Result is err, otherwise calls
f with the wrapped value and returns the result.
Example:
// same as andThen
expect(okVariant.flatMap((v) => ok(v + 1)).unwrap()).toBe(43);
expect(okVariant.flatMap((v) => err("error")).unwrapErr()).toBe("error");
expect(errVariant.flatMap((v) => ok(v + 1)).unwrapErr()).toBe("error");
expect(errVariant.flatMap((v) => err("error1")).unwrapErr()).toBe("error");Alias for flatMap.
Similar to do for Option
Similar to match for Option
- Task monad for async operations
- Use github releases
- Add function syntax and make them curried (e.g.
map(maybeNumber, x => x + 1)) apart from method syntax (e.g.maybeNumber.map(x => x + 1)) - add adapters for common built-in APIs such as
Mapoffsmodule.