0.8.6 • Published 2 years ago

@wentools/option v0.8.6

Weekly downloads
-
License
MIT
Repository
gitlab
Last release
2 years ago

Option

A library with a small set of functions that should give you the ability to write a program without undefined or null, which makes your program easier to reason about and safer.

Installation

This package can be used with both Node and Deno.

Node

npm i @wentools/option

Deno

From a dependency file

// Preferably in deps.ts
export {
  some,
  none,
} from 'https://gitlab.com/wentools/option/-/raw/v0.8.6/src/mod.ts'

Consume directly

import {
  some,
  none,
} from 'https://gitlab.com/wentools/option/-/raw/v0.8.6/src/mod.ts'

Basic usage

The functions some and none creates the Option. If it was the some function that created the Option it will hold a value. If it was the none function it will not hold a value.

Using the methods on the Option you can safely apply transformations on the value, or resolve the value in a safe way.

import { some, none } from '@wentools/option'

const name1 = {
  first: 'John',
  middle: some('William'),
  last: 'Doe',
}

const name2 = {
  first: 'John',
  middle: none(),
  last: 'Doe',
}

console.log(
  `Middle name of ${name1.first} is ${name1.middle
    .map((n) => n.toUpperCase())
    .unwrapOr('nothing')}`
)
// Middle name of John is WILLIAM

console.log(
  `Middle name of ${name2.first} is ${name2.middle
    .map((n) => n.toUpperCase())
    .unwrapOr('nothing')}`
)
// Middle name of John is nothing
import { assumeOption } from '@wentools/option'

const unsafeFunction = (): string | undefined => {
  /* implementation left out for brevity */
}

assumeOption(unsafeFunction()).match({
  some: (x) => console.log(x),
  none: () => console.log('No data'),
})

Functions for creating Option

some

some(DataType): Option<DataType>

Use this function to create an Option that holds a value. If using TypeScript it will try to infer the type. You can also provide the type if you want to be explicit.

const fruit = some('Apple')
fruit.unwrapOr('Banana')
// returns 'Apple'
// Explicit type
const fruit = some<string>('Apple')
fruit.unwrapOr('Banana')
// returns 'Apple'

none

none(): Option<DataType>

Use this function to create an Option that holds no value. If using TypeScript it will try to infer the type. If it can't infer the type it is encouraged to provide the type.

const fruit = none()
fruit.unwrapOr('Banana')
// returns 'Banana'
// Explicit type
const fruit = none<string>()
fruit.unwrapOr('Banana')
// returns 'Banana'

assumeOption

(DataType | undefined | null): Option<DataType>

Use this function to create an Option that might hold a value. A good use case is if you're using a library where you have no control but want to use Option to safely consume it's data.

const fruits = ['Apple']
const fruit = assumeOption(fruits[0])
fruit.unwrapOr('Banana')
// returns 'Apple'
const fruits = ['Apple']
const fruit = assumeOption(fruits[99])
fruit.unwrapOr('Banana')
// returns 'Banana'

Utility functions

transposeOptionToPromise

transposeOptionToPromise(Option<Promise<DataType>>): Promise<Option<DataType>>

Transposes an Option holding a Promise to a Promise holding and Option

const fruit = some(await 'Apple')
await fruit.transposeOptionToPromise().unwrap()
// returns 'Apple'

Option methods

unwrap

unwrap(): DataType

Returns value if Option is some. Will throw if Option is none.

const fruit = some('Apple')
fruit.unwrap()
// returns 'Apple'
const fruit = none()
fruit.unwrap()
// Will throw error.
// It not recommended to use `unwrap`
// unless you know it's a 'some'.

unwrapOr

unwrapOr(DataType): DataType

Returns value of Option if it is some. If Option is none it will return the value of the or parameter.

const fruit = some('Apple')
fruit.unwrapOr('Banana')
// returns 'Apple'
const fruit = none()
fruit.unwrap('Banana')
// returns 'Banana'

unwrapOrElse

unwrapOrElse(() => DataType): DataType

Returns value of Option if it is some. If Option is none it will run the orElse function.

const fruit = some('Apple')
fruit.unwrapOrElse((x) => x.toUpperCase())
// returns 'Apple'
const fruit = none()
fruit.unwrapOrElse((x) => x.toUpperCase())
// returns 'BANANA'

match

match({ some(DataType): MatchExpressionType, none(): MatchExpressionType }): MatchExpressionType

const fruit = some('Apple')
fruit.match({
  some: (x) => x,
  none: () => 'Banana',
})
// returns 'Apple'
const fruit = none()
fruit.match({
  some: (x) => x,
  none: () => 'Banana',
})
// returns 'Banana'

isSome

isSome(): Boolean

Returns true if the Option is some.

const fruit = some('Apple')
fruit.isSome()
// returns `true`
const fruit = none()
fruit.isSome()
// returns `false`

isNone

isNone(): Boolean

Returns true if the Option is none.

const fruit = some('Apple')
fruit.isNone()
// returns `false`
const fruit = none()
fruit.isNone()
// returns `true`

map

map((DataType) => FnReturnType): Option<FnReturnType>

Run a function that replaces the value of some. Will do nothing on none.

const fruit = some('Apple')
fruit.map((x) => x.toUpperCase()).unwrapOr('No fruit :(')
// returns 'APPLE'
const fruit = none()
fruit.map((x) => x.toUpperCase()).unwrapOr('No fruit :(')
// returns 'No fruit :('

mapOr

mapOr((DataType) => FnReturnType, FnReturnType): FnReturnType

Run a function that replaces the value of some. Will replace none with some holding or.

const fruit = some('Apple')
fruit.mapOr((x) => x.toUpperCase(), 'No fruit :(')
// returns 'APPLE'
const fruit = none()
fruit.mapOr((x) => x.toUpperCase(), 'No fruit :(')
// returns 'No fruit :('

mapOrElse

mapOrElse((DataType) => FnReturnType, () => FnReturnType): FnReturnType

Run a function that replaces the value of some. Will replace none with some holding return value of orElse function.

const fruit = some('Apple')
fruit.mapOr(
  (x) => x.toUpperCase(),
  () => 'No fruit'
)
// returns 'APPLE'
const fruit = none()
fruit.mapOr(
  (x) => x.toUpperCase(),
  () => 'No fruit'
)
// returns 'No fruit'

filter

filter((DataType) => Boolean): Option<DataType>

Returns none if Option is none. Will return some with value if predicate returns true, else it will return none.

const fruit = some('Apple')

fruit.filter((x) => x === 'Apple').unwrapOr('No fruit')
// returns 'Apple'

fruit.filter((x) => x === 'Banana').unwrapOr('No fruit')
// returns 'No fruit'
const fruit = none()
fruit.filter((x) => x === 'Apple').unwrapOr('No fruit')
// returns 'No fruit'

zip

zip(Option<SecondDataType>): Option<[DataType, SecondDataType]>

Returns a new Option with the original value and the value of provided option. If either option is none it will return none.

const fruit = some('Apple')
fruit.zip(some('Banana')).unwrapOr(['No apple', 'No banana'])
// returns ['Apple', 'Banana']
const fruit = none()
fruit.zip(some('Banana')).unwrapOr(['No apple', 'No banana'])
// returns ['No apple', 'No banana']

and

and(Option<DataType>): Option<DataType>

Returns none if any is none, else return second option.

const fruit = some('Apple')
fruit.and(some('Banana')).unwrapOr('No fruit')
// returns 'Banana'
const fruit = none()
fruit.and(some('Banana')).unwrapOr('No fruit')
// returns 'No fruit'

andThen

andThen((DataType) => Option<DataType>): Option<DataType>

Returns none if any is none, else returns result of provided function wrapped in an Option. Some languages call this function flatMap.

const fruit = some('Apple')
fruit.andThen((x) => some(x.toUpperCase())).unwrapOr('No fruit')
// returns 'APPLE'
const fruit = none()
fruit.andThen((x) => some(x.toUpperCase())).unwrapOr('No fruit')
// returns 'No fruit'

or

or(Option<DataType>): Option<DataType>

Returns first Option if it is some, else provided Option.

const fruit = some('Apple')
fruit.or(some('Banana')).unwrapOr('No fruit')
// returns 'Apple'
const fruit = none()
fruit.or(some('Banana')).unwrapOr('No fruit')
// returns 'Banana'
const fruit = none()
fruit.or(none()).unwrapOr('No fruit')
// returns 'No fruit'

orElse

orElse(() => Option<DataType>): Option<DataType>

Returns first Option if it is some, else returns result of provided function wrapped in an Option.

const fruit = some('Apple')
fruit.orElse((x) => some(x.toUpperCase())).unwrapOr('No fruit')
// returns 'Apple'
const fruit = none()
fruit.andThen(() => some('Banana')).unwrapOr('No fruit')
// returns 'BANANA'
const fruit = none()
fruit.andThen(() => none()).unwrapOr('No fruit')
// returns 'No fruit'

contains

contains(DataType): boolean

Returns true if the Option is some and holds a value equal to the given value.

const fruit = some('Apple')
fruit.contains('Apple')
// returns true
const fruit = none()
fruit.contains('Apple')
// returns false
const fruit = some('Apple')
fruit.contains('Banana')
// returns false

Maintainers

0.8.5

2 years ago

0.8.4

2 years ago

0.8.6

2 years ago

0.8.1

2 years ago

0.8.0

2 years ago

0.7.1

2 years ago

0.8.3

2 years ago

0.8.2

2 years ago

0.7.0

2 years ago

0.5.2

3 years ago

0.6.0

3 years ago

0.4.2

3 years ago

0.4.1

3 years ago

0.4.0

3 years ago

0.3.1

3 years ago

0.3.0

3 years ago

0.2.2

3 years ago

0.2.1

3 years ago