Option
24 exports from @ontologyio/receta/option.
Everything exported from @ontologyio/receta/option. New here? Start with the Option guide.
Functions
collect
Collects an array of Options into an Option of array.
If all Options are Some, returns Some with array of values. If any Option is None, returns None.
This is useful for operations that must all succeed.
In a pipe, write collect(). A bare collect runs correctly but loses the element type.
function collect<T>(): (options: readonly Option<T>[]) => Option<T[]>function collect<T>(options: readonly Option<T>[]): Option<T[]>// All Some
collect([some(1), some(2), some(3)])
// => Some([1, 2, 3])
// Any None
collect([some(1), none(), some(3)])
// => None
// Real-world: validating multiple fields
const validateForm = (data: SignupForm) => {
const fields = collect([
validateEmail(data.email),
validatePassword(data.password),
validateAge(data.age)
])
return map(fields, ([email, password, age]) => ({
email,
password,
age
}))
}See also partition.
filter
Filters an Option based on a predicate.
If the Option is Some and the predicate returns true, returns the Option unchanged. If the Option is Some and the predicate returns false, returns None. If the Option is None, returns None unchanged.
function filter<T>(option: Option<T>, predicate: (value: T) => boolean): Option<T>function filter<T>(predicate: (value: T) => boolean): (option: Option<T>) => Option<T>// Data-first
filter(some(5), x => x > 0) // => Some(5)
filter(some(-5), x => x > 0) // => None
filter(none(), x => x > 0) // => None
// Data-last (in pipe)
pipe(
fromNullable(user.age),
filter(age => age >= 18),
map(age => `Adult: ${age}`)
)See also map, flatMap.
flatMap
Chains Option-returning functions.
If the Option is Some, applies the function to its value. If the Option is None, returns None unchanged.
This is the monadic bind operation for Option, used to avoid nested Options.
function flatMap<T, U>(option: Option<T>, fn: (value: T) => Option<U>): Option<U>function flatMap<T, U>(fn: (value: T) => Option<U>): (option: Option<T>) => Option<U>// Data-first
declare function findUser(id: string): Option<User>
declare function getEmail(user: User): Option<string>
flatMap(findUser('123'), getEmail)
// Some('user@example.com') or None
// Data-last (in pipe)
pipe(
findUser('123'),
flatMap(getEmail),
flatMap(validateEmail)
)See also map, flatten.
flatten
Flattens a nested Option.
Converts Option<Option<T>> to Option<T>.
In a pipe, write flatten(). A bare flatten runs correctly but loses the element type.
function flatten<T>(): (option: Option<Option<T>>) => Option<T>function flatten<T>(option: Option<Option<T>>): Option<T>// Data-first
flatten(some(some(42))) // => Some(42)
flatten(some(none())) // => None
flatten(none()) // => None
// Data-last (in pipe)
pipe(
some(some(5)),
flatten(),
map(x => x * 2)
) // => Some(10)See also flatMap.
fromNullable
Converts a nullable value to an Option.
If the value is not null or undefined, returns Some with the value. Otherwise, returns None.
function fromNullable<T>(value: T | null | undefined): Option<T>fromNullable(42) // => Some(42)
fromNullable(null) // => None
fromNullable(undefined) // => None
// With array find
const user = fromNullable(users.find(u => u.id === id))fromResult
Converts a Result to an Option, discarding the error.
If the Result is Ok, returns Some with the value. If the Result is Err, returns None.
function fromResult<T, E>(result: Result<T, E>): Option<T>// When you don't care about the specific error
const maybeNumber = fromResult(parseNumber(str))
// Ok(42) => Some(42)
// Err('Invalid') => NoneisNone
Type guard to check if an Option is None.
Narrows the type to None.
function isNone<T>(option: Option<T>): option is Noneconst opt = none()
if (isNone(opt)) {
console.log('No value present')
}isSome
Type guard to check if an Option is Some.
Narrows the type to Some<T>.
function isSome<T>(option: Option<T>): option is Some<T>const opt = some(42)
if (isSome(opt)) {
console.log(opt.value) // TypeScript knows this is safe
}map
Maps over the Some value of an Option.
If the Option is Some, applies the function to its value and returns a new Some. If the Option is None, returns None unchanged.
This is the functor map operation for Option.
function map<T, U>(option: Option<T>, fn: (value: T) => U): Option<U>function map<T, U>(fn: (value: T) => U): (option: Option<T>) => Option<U>// Data-first
map(some(5), x => x * 2) // => Some(10)
map(none(), (x: number) => x * 2) // => None
// Data-last (in pipe)
pipe(
some(5),
map(x => x * 2),
map(x => x + 1)
) // => Some(11)See also flatMap, filter.
match
Pattern matching for Options.
Provides a clean way to handle both Some and None cases.
function match<T, R>(option: Option<T>, patterns: { onSome: (value: T) => R; onNone: () => R; }): Rfunction match<T, R>(patterns: { onSome: (value: T) => R; onNone: () => R; }): (option: Option<T>) => R// Data-first
const message = match(findUser(id), {
onSome: user => `Hello, ${user.name}`,
onNone: () => 'User not found'
})
// Data-last (in pipe)
pipe(
config.get('theme'),
match({
onSome: theme => applyTheme(theme),
onNone: () => applyDefaultTheme()
})
)
// With different return types
const status = match(maybeUser, {
onSome: () => 200,
onNone: () => 404
})See also unwrapOr, unwrapOrElse.
none
Creates a None Option representing absence of a value.
function none<T = never>(): Noneconst result = none()
// => Nonepartition
Partitions an array of Options into Some values and count of Nones.
Returns a tuple of [Some values[], None count].
In a pipe, write partition(). A bare partition runs correctly but loses the element type.
function partition<T>(): (options: readonly Option<T>[]) => [T[], number]function partition<T>(options: readonly Option<T>[]): [T[], number]const results = [some(1), none(), some(2), none(), some(3)]
partition(results)
// => [[1, 2, 3], 2]
// Real-world: processing batch operations
const processUsers = async (ids: string[]) => {
const results = await Promise.all(
ids.map(id => fetchUser(id))
)
const [users, failedCount] = partition(results)
console.log(`Processed ${users.length}, failed ${failedCount}`)
return users
}See also collect.
some
Creates a Some Option containing a value.
function some<T>(value: T): Some<T>const result = some(42)
// => { _tag: 'Some', value: 42 }tap
Performs a side effect on Some value without modifying the Option.
If the Option is Some, calls the function with the value. Returns the original Option unchanged.
Useful for logging, debugging, or other side effects.
function tap<T>(option: Option<T>, fn: (value: T) => void): Option<T>function tap<T>(fn: (value: T) => void): (option: Option<T>) => Option<T>// Data-first
tap(some(42), x => console.log('Value:', x))
// Logs: "Value: 42"
// => Some(42)
// Data-last (in pipe)
pipe(
findUser(id),
tap(user => console.log('Found user:', user.name)),
map(user => user.email)
)See also tapNone, map.
tapNone
Performs a side effect when the Option is None.
If the Option is None, calls the function. Returns the original Option unchanged.
Useful for logging missing values or debugging.
function tapNone<T>(option: Option<T>, fn: () => void): Option<T>function tapNone<T>(fn: () => void): (option: Option<T>) => Option<T>// Data-first
tapNone(none(), () => console.log('No value'))
// Logs: "No value"
// => None
// Data-last (in pipe)
pipe(
findUser(id),
tapNone(() => console.log('User not found')),
unwrapOr(guestUser)
)See also tap.
toNullable
Converts an Option to a nullable value.
If the Option is Some, returns the value. If the Option is None, returns null.
Use this when interfacing with APIs that expect null for missing values.
In a pipe, write toNullable(). A bare toNullable runs correctly but loses the element type.
function toNullable<T>(): (option: Option<T>) => T | nullfunction toNullable<T>(option: Option<T>): T | null// Data-first
toNullable(some(42)) // => 42
toNullable(none()) // => null
// Data-last (in pipe)
pipe(
findUser(id),
map(u => u.name),
toNullable()
) // 'John' or null
// Interfacing with external API
const apiPayload = {
userId: toNullable(maybeUserId),
metadata: toNullable(maybeMetadata)
}See also fromNullable.
toResult
Converts an Option to a Result.
If the Option is Some, returns Ok with the value. If the Option is None, returns Err with the provided error.
function toResult<T, E>(option: Option<T>, error: E): Result<T, E>function toResult<E>(error: E): <T>(option: Option<T>) => Result<T, E>import { flatMap } from '@ontologyio/receta/result'
// Data-first
toResult(some(42), 'No value') // => Ok(42)
toResult(none(), 'No value') // => Err('No value')
// Data-last (in pipe)
pipe(
findUser(id),
toResult({ code: 'USER_NOT_FOUND', message: 'User not found' }),
flatMap(user => validateUser(user))
)
// With a config lookup
pipe(
config.get('apiKey'),
toResult('Missing API key in config')
)See also fromResult.
tryCatch
Wraps a potentially throwing function in an Option.
If the function executes successfully, returns Some with the value. If it throws, returns None.
function tryCatch<T>(fn: () => T): Option<T>const parseJSON = (str: string) =>
tryCatch(() => JSON.parse(str))
parseJSON('{"name":"John"}')
// => Some({ name: 'John' })
parseJSON('invalid json')
// => Noneunwrap
Extracts the value from a Some Option or throws an error.
If the Option is Some, returns the value. If the Option is None, throws an error.
Use this when you're certain the value exists. Prefer unwrapOr or unwrapOrElse for safer alternatives.
function unwrap<T>(option: Option<T>): Tunwrap(some(42)) // => 42
unwrap(none()) // throws Error: Cannot unwrap NoneSee also unwrapOr, unwrapOrElse.
unwrapOr
Extracts the value from an Option or returns a default.
If the Option is Some, returns the value. If the Option is None, returns the default value.
function unwrapOr<T>(option: Option<T>, defaultValue: T): Tfunction unwrapOr<T>(defaultValue: T): (option: Option<T>) => T// Data-first
unwrapOr(some(42), 0) // => 42
unwrapOr(none(), 0) // => 0
// Data-last (in pipe)
pipe(
findUser(id),
map(u => u.name),
unwrapOr('Guest')
) // 'John' or 'Guest'See also unwrapOrElse, unwrap.
unwrapOrElse
Extracts the value from an Option or computes a default.
If the Option is Some, returns the value. If the Option is None, calls the function to compute a default.
Use this when the default value is expensive to compute.
function unwrapOrElse<T>(option: Option<T>, fn: () => T): Tfunction unwrapOrElse<T>(fn: () => T): (option: Option<T>) => T// Data-first
unwrapOrElse(some(42), () => expensiveComputation()) // => 42
unwrapOrElse(none(), () => expensiveComputation()) // computed value
// Data-last (in pipe)
pipe(
config.get('timeout'),
unwrapOrElse(() => DEFAULT_TIMEOUT)
)See also unwrapOr, unwrap.
Types
None
Represents the absence of a value.
interface None {
readonly _tag: 'None'
}Option
Option type representing either a value (Some) or no value (None).
type Option<T> = Some<T> | Nonetype MaybeUser = Option<User>
const present: MaybeUser = { _tag: 'Some', value: { name: 'John' } }
const absent: MaybeUser = { _tag: 'None' }Some
Represents a value that exists.
interface Some<T> {
readonly _tag: 'Some'
readonly value: T
}