見出し画像

type-festライブラリのDeepMerge型を使ったワークアラウンドについて

こんにちわ。nap5です。

type-festライブラリのDeepMerge型を使ったワークアラウンドの紹介です。



zennにも似た内容でPOSTしてみました。


hashnodeにもPOSTしてみました。


今回は少し応用した形で紹介したいと思います。

こちらの関数になります。

import { mergeDeepWith } from 'ramda'

import type { MergeDeep, MergeDeepOptions } from 'type-fest'

// https://github.com/jhildenbiddle/mergician/issues/1
type ObjectLiteral = Record<string, unknown>

const mergeDeep = <Source, Destination, Options extends MergeDeepOptions = {}>(
  source: Source,
  destination: Destination,
  options?: Options
): MergeDeep<Source, Destination, Options> => {
  // https://github.com/sindresorhus/type-fest/blob/main/source/merge-deep.d.ts#L416-L456
  // Make your implementation ...
  const mergedObj = mergeDeepWith<Source, Destination>(
    (x, y) => {
      // https://github.com/denoland/deno/blob/main/ext/node/polyfills/util.ts#L30-L32
      if (Array.isArray(x) && Array.isArray(y)) {
        return [...x, ...y]
      }
      if (x) return x
      if (y) return y
      return null
    },
    source,
    destination
  )
  return mergedObj
}

const merge = <
  Source,
  Destination,
  Options extends MergeDeepOptions = { recurseIntoArrays: true }
  // https://github.com/sindresorhus/type-fest/blob/main/source/merge-deep.d.ts#L416-L443
>(
  ...objects: ObjectLiteral[]
): MergeDeep<Source, Destination, Options> => {
  // https://github.com/sindresorhus/type-fest/blob/main/source/merge-deep.d.ts#L416-L456
  // Make your implementation ...
  const result = objects.reduce((acc: ObjectLiteral, cur: ObjectLiteral) => {
    acc = mergeDeep(acc, cur)
    return acc
  }, {}) as MergeDeep<Source, Destination, Options>
  return result
}

export { mergeDeep, merge }


これを使ったデモコードはこちらになります。


ポイントはNeatType型を用意しておくことです。

  type NeatType = {
    a: {
      b: number;
      c: boolean;
      d: boolean[];
    };
    life: number;
    items: number[];
    users: {
      name: string;
      id: number;
    }[];
    name: string;
  };

  const result = merge<NeatType, {}>(a, b, c);


簡単ですが、以上です。

いいなと思ったら応援しよう!