@wentools/option v0.8.6
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/optionDeno
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 nothingimport { 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 trueconst fruit = none()
fruit.contains('Apple')
// returns falseconst fruit = some('Apple')
fruit.contains('Banana')
// returns false