diff --git a/.changeset/rare-deers-sparkle.md b/.changeset/rare-deers-sparkle.md new file mode 100644 index 00000000..8dda7bcc --- /dev/null +++ b/.changeset/rare-deers-sparkle.md @@ -0,0 +1,21 @@ +--- +'@metaplex-foundation/umi-options': minor +--- + +`wrapNullable` didn't account for an undefined input and would result in a return value of `some(undefined)` causing `isNone` checks to not pass if `undefined` was the `nullable` value. + +```ts +export const wrapNullable = (nullable: Nullable): Option => + nullable !== null ? some(nullable) : none(); +``` + +Added a `wrapNullish` function to check for both `null` and undefined which will return the value of `none()` if `null` or `undefined` is the presented `nullish` value. + +```ts +export const wrapNullish = (nullish: Nullish): Option => + nullish !== null && nullish !== undefined ? some(nullish) : none(); +``` + +- `Nullish` type added. +- `wrapNullish` function added. +- Tests for `wrapNullish` added. diff --git a/packages/umi-options/src/common.ts b/packages/umi-options/src/common.ts index ea620046..8261d235 100644 --- a/packages/umi-options/src/common.ts +++ b/packages/umi-options/src/common.ts @@ -4,6 +4,12 @@ */ export type Nullable = T | null; +/** + * Defines a type `T` that can also be `null` or `undefined`. + * @category Utils — Options + */ +export type Nullish = T | null | undefined; + /** * An implementation of the Rust Option type in JavaScript. * It can be one of the following: diff --git a/packages/umi-options/src/unwrapOption.ts b/packages/umi-options/src/unwrapOption.ts index d29e4ba6..0930447d 100644 --- a/packages/umi-options/src/unwrapOption.ts +++ b/packages/umi-options/src/unwrapOption.ts @@ -1,4 +1,4 @@ -import { Nullable, Option, isSome, none, some } from './common'; +import { Nullable, Nullish, Option, isSome, none, some } from './common'; /** * Unwraps the value of an {@link Option} of type `T` @@ -24,6 +24,14 @@ export function unwrapOption( export const wrapNullable = (nullable: Nullable): Option => nullable !== null ? some(nullable) : none(); +/** + * Wraps a nullish value into an {@link Option}. + * + * @category Utils — Options + */ +export const wrapNullish = (nullish: Nullish): Option => + nullish !== null && nullish !== undefined ? some(nullish) : none(); + /** * Unwraps the value of an {@link Option} of type `T`. * If the option is a {@link Some}, it returns its value, diff --git a/packages/umi-options/test/unwrapOption.test.ts b/packages/umi-options/test/unwrapOption.test.ts index a798e495..5b5e2242 100644 --- a/packages/umi-options/test/unwrapOption.test.ts +++ b/packages/umi-options/test/unwrapOption.test.ts @@ -1,5 +1,5 @@ import test from 'ava'; -import { none, some, unwrapOption, wrapNullable } from '../src'; +import { none, some, unwrapOption, wrapNullable, wrapNullish } from '../src'; test('it can unwrap an Option as a Nullable', (t) => { t.is(unwrapOption(some(42)), 42); @@ -34,3 +34,12 @@ test('it can wrap a Nullable as an Option', (t) => { t.deepEqual(wrapNullable(null), none()); t.deepEqual(wrapNullable(null), none()); }); + +test('it can wrap a Nullish as an Option', (t) => { + t.deepEqual(wrapNullish(42), some(42)); + t.deepEqual(wrapNullish('hello'), some('hello')); + t.deepEqual(wrapNullish(false), some(false)); + t.deepEqual(wrapNullish(undefined), none()); + t.deepEqual(wrapNullish(null), none()); + t.deepEqual(wrapNullish(null), none()); +});