js/BigInt doesn't work as hash map key.
Hash maps require keys that correctly support hashCode and equals.
(https://clojure.org/reference/data_structures#Maps)
-
> Returns the hash code of its argument. Note this is the hash code
consistent with =.
> (https://cljs.github.io/api/cljs.core/hash)
Now if I check hash of js/Number it's always the same for the same number:
(hash (js/Number 4)) ;; => 4
(hash (js/Number 4)) ;; => 4
But if I do the same for js/BigInt, it's different each time:
(hash (js/BigInt 4)) ;; => 15
(hash (js/BigInt 4)) ;; => 16
(tested using online cljs repl: http://clojurescript.net/).
This suggests that hash function doesn't work for js/BigInt and therefore when computing place in the hashmap:
A hash table uses a hash function to compute an index, also called a hash code, into an array of buckets or slots, from which the desired value can be found.
(https://en.wikipedia.org/wiki/Hash_table#Hashing)
incorrect place is computed (as based on the hash function, the new js/BigInt is different value than the js/BigInt inside the hash map).
The reason it works with some hash maps is due to different implementation used in the 2 cases. ClojureScript implements more interfaces for hash maps: https://cljs.github.io/api/cljs.core/#IMap
(type {0 0 1 1 2 2 3 3 (js/BigInt 4) 4 5 5 7 7 8 8}) ;; => cljs.core/PersistentArrayMap
(type {0 0 1 1 2 2 3 3 (js/BigInt 4) 4 5 5 7 7 8 8 9 9}) ;; => cljs.core/PersistentHashMap
You can see example when implementation is switched here: https://cljs.github.io/api/cljs.core/PersistentArrayMap based on HASHMAP-THRESHOLD property.
Some more details about why different implementations exist: https://stackoverflow.com/questions/16516176/what-is-the-difference-between-clojures-apersistentmap-implementations
So if hash map is small, it works like array and for equality hash is not used, only = is. Then, when hash map becomes bigger, first hash is used to determine place in the hash map and = is used to get the concrete value in the position.
That's more or less how it works.