custom mergeInto clearing "leaf records" #317
Replies: 2 comments
-
I've just released v5.1 where I've expose some of the internal util functions. These functions will make it easier to do this without having to redefine them. Here's what I came up with: import { type DeepMergeValueReference, ObjectType, deepmergeIntoCustom, getKeys, getObjectType, objectHasProperty } from "deepmerge-ts";
function handleRecords(
target: DeepMergeValueReference<Record<PropertyKey, unknown>>,
values: ReadonlyArray<Record<PropertyKey, unknown>>
) {
// Loop through all the keys of all the values.
for (const key of getKeys(values)) {
const propValues = [];
// Get all the values under the current key.
for (const value of values) {
if (objectHasProperty(value, key)) {
propValues.push(value[key]);
}
}
// Should never happen but good to check anyway.
if (propValues.length === 0) {
continue;
}
// Set the result value.
const result = {};
target.value[key] = result;
// Look for any nested records.
const subrecords = propValues.filter(
(value): value is Record<PropertyKey, unknown> =>
getObjectType(value) === ObjectType.RECORD
);
// If there are any, handle them.
if (subrecords.length > 0) {
const subtarget = { value: result };
handleRecords(subtarget, subrecords);
}
}
}
export const myCustomMergeInto = deepmergeIntoCustom({
mergeOthers(target, values) {
// Get the type of the target.
const type = getObjectType(target.value);
// If it wasn't a record, overwrite it to be one.
if (type !== ObjectType.RECORD) {
target.value = {};
}
// We now know that the target is a record so make that type assertion.
const recordTarget = target as DeepMergeValueReference<
Record<PropertyKey, unknown>
>;
// Find all the values that are records.
const recordValues = values.filter(
(value): value is Record<PropertyKey, unknown> =>
getObjectType(value) === ObjectType.RECORD
);
// Handle those records.
if (recordValues.length > 0) {
handleRecords(recordTarget, recordValues);
}
},
}); |
Beta Was this translation helpful? Give feedback.
-
Thank you for the quick response. I had a few issues with your example. First of all Also, the customization code looks very complex and I ended up writing my own little merge helper utility for my use case. It's probably way less powerful than yours and I didn't optimize for speed at all. I published it as @shigen/merge in case you are interested. |
Beta Was this translation helpful? Give feedback.
-
This library seems very powerful but I don't really understand the custom API.
I hope this example illustrates what I am trying to do.
What I want is basically empty objects for all nodes that don't have nested children.
I suppose this should work somehow with
mergeRecords
but I don't understand how I can apply the callback only at specific levels of depth. When I return the default merge action, my custom callback doesn't get called again and when I try to apply the specifiedmergeRecords
I run into an infinite loop.Beta Was this translation helpful? Give feedback.
All reactions