receta

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.

Data-last
function collect<T>(): (options: readonly Option<T>[]) => Option<T[]>
Data-first
function collect<T>(options: readonly Option<T>[]): Option<T[]>
Example
// 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.

Data-first
function filter<T>(option: Option<T>, predicate: (value: T) => boolean): Option<T>
Data-last
function filter<T>(predicate: (value: T) => boolean): (option: Option<T>) => Option<T>
Example
// 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.

Data-first
function flatMap<T, U>(option: Option<T>, fn: (value: T) => Option<U>): Option<U>
Data-last
function flatMap<T, U>(fn: (value: T) => Option<U>): (option: Option<T>) => Option<U>
Example
// 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.

Data-last
function flatten<T>(): (option: Option<Option<T>>) => Option<T>
Data-first
function flatten<T>(option: Option<Option<T>>): Option<T>
Example
// 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.

Signature
function fromNullable<T>(value: T | null | undefined): Option<T>
Example
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.

Signature
function fromResult<T, E>(result: Result<T, E>): Option<T>
Example
// When you don't care about the specific error
const maybeNumber = fromResult(parseNumber(str))
// Ok(42) => Some(42)
// Err('Invalid') => None

isNone

Type guard to check if an Option is None.

Narrows the type to None.

Signature
function isNone<T>(option: Option<T>): option is None
Example
const 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>.

Signature
function isSome<T>(option: Option<T>): option is Some<T>
Example
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.

Data-first
function map<T, U>(option: Option<T>, fn: (value: T) => U): Option<U>
Data-last
function map<T, U>(fn: (value: T) => U): (option: Option<T>) => Option<U>
Example
// 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.

Data-first
function match<T, R>(option: Option<T>, patterns: { onSome: (value: T) => R; onNone: () => R; }): R
Data-last
function match<T, R>(patterns: { onSome: (value: T) => R; onNone: () => R; }): (option: Option<T>) => R
Example
// 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.

Signature
function none<T = never>(): None
Example
const result = none()
// => None

partition

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.

Data-last
function partition<T>(): (options: readonly Option<T>[]) => [T[], number]
Data-first
function partition<T>(options: readonly Option<T>[]): [T[], number]
Example
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.

Signature
function some<T>(value: T): Some<T>
Example
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.

Data-first
function tap<T>(option: Option<T>, fn: (value: T) => void): Option<T>
Data-last
function tap<T>(fn: (value: T) => void): (option: Option<T>) => Option<T>
Example
// 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.

Data-first
function tapNone<T>(option: Option<T>, fn: () => void): Option<T>
Data-last
function tapNone<T>(fn: () => void): (option: Option<T>) => Option<T>
Example
// 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.

Data-last
function toNullable<T>(): (option: Option<T>) => T | null
Data-first
function toNullable<T>(option: Option<T>): T | null
Example
// 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.

Data-first
function toResult<T, E>(option: Option<T>, error: E): Result<T, E>
Data-last
function toResult<E>(error: E): <T>(option: Option<T>) => Result<T, E>
Example
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.

Signature
function tryCatch<T>(fn: () => T): Option<T>
Example
const parseJSON = (str: string) =>
  tryCatch(() => JSON.parse(str))

parseJSON('{"name":"John"}')
// => Some({ name: 'John' })

parseJSON('invalid json')
// => None

unwrap

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.

Signature
function unwrap<T>(option: Option<T>): T
Example
unwrap(some(42)) // => 42
unwrap(none()) // throws Error: Cannot unwrap None

See 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.

Data-first
function unwrapOr<T>(option: Option<T>, defaultValue: T): T
Data-last
function unwrapOr<T>(defaultValue: T): (option: Option<T>) => T
Example
// 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.

Data-first
function unwrapOrElse<T>(option: Option<T>, fn: () => T): T
Data-last
function unwrapOrElse<T>(fn: () => T): (option: Option<T>) => T
Example
// 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.

Signature
interface None {
  readonly _tag: 'None'
}

Option

Option type representing either a value (Some) or no value (None).

Signature
type Option<T> = Some<T> | None
Example
type MaybeUser = Option<User>

const present: MaybeUser = { _tag: 'Some', value: { name: 'John' } }
const absent: MaybeUser = { _tag: 'None' }

Some

Represents a value that exists.

Signature
interface Some<T> {
  readonly _tag: 'Some'
  readonly value: T
}

On this page