Assign default properties, recursively. Lightweight and Fast.
Install package:
# yarn
yarn add defu
# npm
npm install defu
# pnpm
pnpm install defu
import { defu } from "defu";
const options = defu(object, ...defaults);
Leftmost arguments have more priority when assigning defaults.
import { defu } from "defu";
console.log(defu({ a: { b: 2 } }, { a: { b: 1, c: 3 } }));
// => { a: { b: 2, c: 3 } }
const { defu } = require("defu");
Sometimes default merging strategy is not desirable. Using createDefu
we can create a custom instance with different merging strategy.
This function accepts obj
(source object), key
and value
(current value) and should return true
if applied custom merging.
Example: Sum numbers instead of overriding
import { createDefu } from "defu";
const ext = createDefu((obj, key, value) => {
if (typeof obj[key] === "number" && typeof value === "number") {
obj[key] += value;
return true;
}
});
ext({ cost: 15 }, { cost: 10 }); // { cost: 25 }
Using defuFn
, if user provided a function, it will be called with default value instead of merging.
It can be useful for default values manipulation.
Example: Filter some items from defaults (array) and add 20 to the count default value.
import { defuFn } from "defu";
defuFn(
{
ignore: (val) => val.filter((item) => item !== "dist"),
count: (count) => count + 20,
},
{
ignore: ["node_modules", "dist"],
count: 10,
},
);
/*
{
ignore: ['node_modules'],
count: 30
}
*/
Note: if the default value is not defined, the function defined won't be called and kept as value.
defuArrayFn
is similar to defuFn
but only applies to array values defined in defaults.
Example: Filter some items from defaults (array) and add 20 to the count default value.
import { defuArrayFn } from 'defu'
defuArrayFn({
ignore: (val) => val.filter(i => i !== 'dist'),
count: () => 20
}, {
ignore: [
'node_modules',
'dist'
],
count: 10
})
/*
{
ignore: ['node_modules'],
count: () => 20
}
*/
Note: the function is called only if the value defined in defaults is an aray.
object
and defaults
are not modifiednull
and undefined
) are skipped. Please use defaults-deep or omit-deep or lodash.defaultsdeep if you need to preserve or different behavior.__proto__
and constructor
keys will be skipped to prevent security issues with object pollution.array
values (if default property is defined)console.log(defu({ array: ["b", "c"] }, { array: ["a"] }));
// => { array: ['b', 'c', 'a'] }
We expose Defu
as a type utility to return a merged type that follows the rules that defu follows.
import type { Defu } from 'defu'
type Options = Defu<{ foo: 'bar' }, [{}, { bar: 'baz' }, { something: 42 }]>
// returns { foo: 'bar', bar: 'baz', 'something': 42 }
MIT. Made with 💖