Closed lveillard closed 6 months ago
This might be a bug in current
, but we need a repro to be sure. (See also comments in the PR)
immer@10.0.4
Well while the issue with the nested objects in Symbols is fixed, I still need to use my version of deepCurrent, i guess it is because I check extra stuff:
type Drafted<T> = T | Draft<T>;
// Recursively define the type to handle nested structures
type DeepCurrent<T> =
T extends Array<infer U> ? Array<DeepCurrent<U>> : T extends object ? { [K in keyof T]: DeepCurrent<T[K]> } : T;
export const deepCurrent = <T>(obj: Drafted<T>): any => {
if (Array.isArray(obj)) {
// Explicitly cast the return type for arrays
return obj.map((item) => current(item)) as DeepCurrent<T>;
} else if (obj && typeof obj === 'object') {
// Handle non-null objects
const plainObject = isDraft(obj) ? current(obj) : obj;
const result: any = {};
Object.entries(plainObject).forEach(([key, value]) => {
// Use the key to dynamically assign the converted value
result[key] = current(value);
});
// Explicitly cast the return type for objects
return result as DeepCurrent<T>;
} else {
// Return the value directly for non-objects and non-arrays
return obj as DeepCurrent<T>;
}
};
Well it actually works, I don't need it to be recursive anymore. I will change its name to "saferCurrent" tho as it does not throw error if the object is not a draft
type Drafted<T> = T | Draft<T>;
// Recursively define the type to handle nested structures
type DeepCurrent<T> =
T extends Array<infer U> ? Array<DeepCurrent<U>> : T extends object ? { [K in keyof T]: DeepCurrent<T[K]> } : T;
export const deepCurrent = <T>(obj: Drafted<T>): any => {
if (Array.isArray(obj)) {
// Explicitly cast the return type for arrays
return obj.map((item) => current(item)) as DeepCurrent<T>;
} else if (obj && typeof obj === 'object') {
// Handle non-null objects
const plainObject = isDraft(obj) ? current(obj) : obj;
const result: any = {};
Object.entries(plainObject).forEach(([key, value]) => {
// Use the key to dynamically assign the converted value
result[key] = isDraft(value) ? current(value) : value;
});
// Explicitly cast the return type for objects
return result as DeepCurrent<T>;
} else {
// Return the value directly for non-objects and non-arrays
return obj as DeepCurrent<T>;
}
};
Hello!
Issue I'm struggling to mutate an object as i need to split it and then add different things to each new end. The problem is that the original object has nested objects, so when duplicating, the original nested objects get referenced.
Lets say i have
And then i split a to:
if i do this in the same draft and i modify b:2 it affects both.
I'm trying to sue structuredClone, structuredClone(current(a)) but they don't work because the draft are embeded.
With some real data:
Basically I split the original object which has $id: ['id1' ,'id2'] into an array with two objects.
This works at the root node, i get an array with two different BzId "_0" and "_1" But if i modify the nested object, it gets modified in both places.
I tried to use this:
...structuredClone(subNode),
But it gets this error:
[object Array] could not be cloned.
I guess this happens when it arrives to the nested structures created by immer.Is there a way in immer to deeply clone an object and drop?
or the only way i can do right is a deepCurrent() and then use structureCloned over the result?
Immer version: Using immer (9.0.21 as 10.0.x does not work with symbols that have references to objects)