The immer docs state "The keys of a map are never drafted! This is done to avoid confusing semantics and keep keys always referentially equal", but I'm having a tough time understanding what is meant by this.
I expected this to mean that using a draft object as a key in a draft Map
/Set
would automatically dereference the key as though I had called e.g. map.set(original(key) || key, value)
. However, that doesn't seem to be the case, and I can't figure what is meant by that statement.
Here are some examples that demonstrate what I mean. I expected true
for all of these logs.
const { enableMapSet, produce } = immer;
enableMapSet();
const collection = {
map: new Map(),
set: new Set(),
storedAsObject: {},
storedAsDraft: {},
};
collection.set.add(collection.storedAsObject);
collection.map.set(collection.storedAsObject, 'value');
const newCollection = produce(collection, (draft) => {
console.log(draft.set.has(draft.storedAsObject)); // false
console.log(draft.map.has(draft.storedAsObject)); // false
draft.set.add(draft.storedAsDraft);
draft.map.set(draft.storedAsDraft, 'value');
});
console.log(newCollection.set.has(newCollection.storedAsDraft)); // true
console.log(newCollection.map.has(newCollection.storedAsDraft)); // false
<script src="https://unpkg.com/immer@6.0.3/dist/immer.umd.production.min.js"></script>
In particular, the difference in the last two seems like a bug, but the special behavior the docs are talking about only call out maps, so I'm not sure.