Provides a collection of helper functions for operations on maybe types.
This package seeks to recreate idioms common in strongly typed functional programming languages, with heavy influence from the Data.Maybe Haskell package.
pnpm add @freckle/maybeThis package is ESM-only ("type": "module"). Prefer import. require('@freckle/maybe')
works on Node 22.12+ via require(esm), but not on older Node or under CJS-only bundlers.
Operations are used to refine an input from being possibly null or undefined:
import {fromJust, fromMaybe, maybe} from '@freckle/maybe'
// Return input from a user, if any:
declare function getUserInput(): ?string
const mUserInput = getUserInput()
// Go from ?string -> string:
const input = fromMaybe(() => 'No input', mUserInput)
// Run a function on ?string with a default:
const capitalized = maybe(() => 'No input to capitalize', capitalize, mUserInput)
// Or produce an error on null | undefined to make future execution more predictable:
const userInput = fromJust(mUserInput, 'No input was given!')Other operations carry the possibly null value after applying a function:
import {mmap, mthen} from '@freckle/maybe'
// Return input from a user, if any:
declare function getUserInput(): ?string
// Function that does not handle a null | undefined value:
declare function transform(input: string): string
const mUserInput = getUserInput()
const mTransformed = mmap(transform, mUserInput)
// => null | undefined | transform(mUserInput)
// Alternate form that is more helpful for control flow:
mthen(mTransformed, (transformedUserInput: string) => {
// Process value
})For dealing with Arrays that may contain null or undefined elements:
import {catMaybes, mapMaybes} from '@freckle/maybe'
const arr = [
null,
'foo',
undefined,
'bar'
]
const out = catMaybes(arr)
console.log(out) // => ['foo', 'bar']
const padString = (input: string) => ` ${input}`
const mapped = mapMaybes(arr, padString)
console.log(mapped) // => [' foo', ' bar']Two operations are tailored to use with React:
import {mEffect, asHTMLAttributeValue} from '@freckle/maybe'
type Props = {
myInput: ?string
}
const MyComponent = (props: Props): React.Node => {
// This prop may be string | undefined | null
const possibleInput = props.myInput
React.useEffect(() => {
mEffect(possibleInput, input =>
// Call a side effect that does not handle a null value:
sideEffect(input)
)
}, [possibleInput])
// Rendering an element with an attribute from a maybe value:
const attrObj = {'my-attribute': asHTMLAttributeValue(possibleInput)}
// If input is not a string, <div> is rendered;
// otherwise: <div my-attribute="..." />
return <div {...attrObj} />
}- Package manager: pnpm (Node version pinned in
.nvmrc) pnpm build—tsc, emits todist/pnpm test— Vitestpnpm coverage— Vitest with coverage, gated at 70% (lines/branches/functions/statements)pnpm typecheck—tsc --noEmit, includes test filespnpm lint— ESLintpnpm format/pnpm format-check— Prettierpnpm knip— unused files/dependencies/exports- CI runs all of the above on every PR, plus a check that
dist/is up to date
See RELEASE.md for more details.