Welcome! Please see the About page for a little more info on how this works.
If I run
(s/conform (s/map-of (s/or :keyword keyword? :string string?) any?) {:a 1})
I get
{:a 1}
instead of
{[:keyword :a] 1}
Is that expected?
One consequence of that is that if I try to s/unform
s/unform
(s/unform (s/map-of (s/or :keyword keyword? :string string?) any?) {:a 1})
I get an exception, because :a is not a valid conformed value for s/or.
:a
s/or
I bumped into this issue using spec-tools. Its implementation of explain-data calls s/unform (https://github.com/metosin/spec-tools/blob/master/src/spec_tools/core.cljc#L446). I'm trying to figure out whether this is a spec or spec-tools issue.
Yes, that is the default behavior for a couple reasons - first, map keys are typically simple values - keywords, strings, longs and the conformed values are identical, second it's better perf not to do this if you don't need it.
You can request this with :conform-keys true though if you need it, as it says in map-of docstring. https://clojure.github.io/spec.alpha/clojure.spec.alpha-api.html#clojure.spec.alpha/map-of
:conform-keys true
map-of