@homer0/deep-assign
TypeScript icon, indicating that this package has built-in type declarations

3.0.4 • Public • Published

🧬 Deep assign

Deep merge (and copy) of objects and Arrays using native spread syntax.

🍿 Usage

If you are wondering why I built this, go to the Motivation section.

⚙️ Examples

Simple merge

import { deepAssign } from '@homer0/deep-assign';

const generateOptions = (options = {}) => deepAssign(
  {
    title: 'myApp',
    sections: [{ title: 'about', enabled: true }],
    enabled: false,
    features: {
      accounts: true,
      blog: false,
    },
  },
  options,
);

console.log(generateOptions({
  title: 'my AWESOME app',
  sections: [{ title: 'ME', url: '/me' }, 'projects'],
  enabled: true,
  features: {
    blog: true,
    projects: true,
  },
  extras: null,
}));
/**
 * {
 *   title: 'my AWESOME app',
 *   sections: [
 *     { title: 'ME', enabled: true, url: '/me' },
 *     'projects',
 *   ],
 *   enabled: true,
 *   features: {
 *     accounts: true,
 *     blog: true,
 *     projects: true,
 *   },
 *   extras: null,
 * }

Symbols as keys

import { deepAssign } from '@homer0/deep-assign';

const FEATURES_KEY = Symbol('features');

const generateOptions = (options = {}) => deepAssign(
  {
    title: 'myApp',
    [FEATURES_KEY]: {
      accounts: true,
      blog: false,
    },
  },
  options,
);

console.log(generateOptions({
  title: 'my AWESOME app',
  [FEATURES_KEY]: {
    blog: true,
    projects: true,
  },
}));
/**
 * {
 *   title: 'my AWESOME app',
 *   [Symbol(features)]: {
 *     accounts: true,
 *     blog: true,
 *     projects: true,
 *   },
 * }

Arrays concatenation

This feature allows for Arrays found inside properties to be concatenated instead of merging them.

import { deepAssignWithConcat } from '@homer0/deep-assign';

const generateOptions = (options = {}) => deepAssignWithConcat(
  {
    title: 'myApp',
    sections: [{ title: 'about', enabled: true }],
  },
  options,
);

console.log(generateOptions({
  title: 'my AWESOME app',
  sections: [{ title: 'ME', url: '/me' }, 'projects'],
}));
/**
 * {
 *   title: 'my AWESOME app',
 *   sections: [
 *     { title: 'about', enabled: true },
 *     { title: 'ME', url: '/me' },
 *     'projects',
 *   ],
 * }

Arrays overwrite

This allows you to, instead of merging Arrays inside object properties, to overwrite them entirely.

import { deepAssignWithOverwrite } from '@homer0/deep-assign';

const generateOptions = (options = {}) => deepAssignWithOverwrite(
  {
    title: 'myApp',
    sections: [{ title: 'about', enabled: true }],
  },
  options,
);

console.log(generateOptions({
  title: 'my AWESOME app',
  sections: [{ title: 'ME', url: '/me' }, 'projects'],
}));
/**
 * {
 *   title: 'my AWESOME app',
 *   sections: [
 *     { title: 'ME', url: '/me' },
 *     'projects',
 *   ],
 * }

Arrays shallow merge

If you want to merge the Arrays, but don't want it to go as deep as the objects inside, you can use do a "shallow merge".

import { deepAssignWithShallowMerge } from '@homer0/deep-assign';

const generateOptions = (options = {}) => deepAssignWithShallowMerge(
  {
    title: 'myApp',
    sections: [{ title: 'about', enabled: true }],
  },
  options,
);

console.log(generateOptions({
  title: 'my AWESOME app',
  sections: [{ title: 'ME', url: '/me' }, 'projects'],
}));
/**
 * {
 *   title: 'my AWESOME app',
 *   sections: [
 *     { title: 'ME', url: '/me' },
 *     'projects',
 *   ],
 * }

🤘 Development

As this project is part of the packages monorepo, some of the tooling, like lint-staged and husky, are installed on the root's package.json.

Tasks

Task Description
lint Lints the package.
test Runs the unit tests.
build Transpiles and bundles the project.
types:check Validates the TypeScript types.

Motivation

This used to be part of the wootils package, my personal lib of utilities, but I decided to extract them into individual packages, as part of the packages monorepo, and take the oportunity to migrate them to TypeScript.

Now, the reason I created this, rather than use merge from my own object-utils lib, it's because extend doesn't support symbols as keys, they don't want to support for it, and since merging with spread syntax already does... "how hard could it be to use spread syntax recursively?".

Package Sidebar

Install

npm i @homer0/deep-assign

Weekly Downloads

0

Version

3.0.4

License

MIT

Unpacked Size

59.2 kB

Total Files

10

Last publish

Collaborators

  • homer0