Skip to content

Add mergeOptions function #414

@aleclarson

Description

@aleclarson

Throwing this in here to eventually be added to Radashi. Currently, it depends on Merge from the type-fest npm package, which isn't ideal. We'll have to replace it before this can be added to Radashi.

The return type is pretty spooky, so I think there's value in such a function. Its purpose is to merge two optional objects in a type-safe way.

import type { Merge } from 'type-fest'

type Simplify<T> = {} & { [K in keyof T]: T[K] }

type UndefinedToPartial<T> = undefined extends T
  ? Partial<Exclude<T, undefined>>
  : T

export function mergeOptions<
  const A extends object | undefined,
  const B extends object | undefined,
>(
  a: A,
  b: B
): [A] extends [undefined]
  ? B // If A is always undefined, then B is the result.
  : [B] extends [undefined]
    ? A // If B is always undefined, then A is the result.
    :
        | (B extends object
            ? // Perform an { ...A, ...B } merge.
              Simplify<Merge<UndefinedToPartial<A>, B>>
            : never)
        | (undefined extends B
            ? Simplify<
                A & {
                  // This ensures all properties of B are accessible,
                  // even when B is undefined.
                  [K in B extends object
                    ? Exclude<keyof B, keyof A>
                    : never]?: undefined
                }
              >
            : never)
        | ([undefined, undefined] extends [A, B]
            ? // If both can be undefined, then undefined is possible.
              undefined
            : never)

export function mergeOptions(a: object | undefined, b: object | undefined): any {
  if (a === undefined) {
    return b
  }
  if (b === undefined) {
    return a
  }
  return {
    ...a,
    ...b,
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    new featureThis PR adds a new function or extends an existing one

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions