🧬 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,
}));
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,
},
}));
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'],
}));
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'],
}));
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'],
}));
🤘 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?".