Welcome! Please see the About page for a little more info on how this works.

0 votes
in ClojureScript by
$ planck 
ClojureScript 1.10.339
cljs.user=> #js {:foo/bar 1}
JavaScript literal keys must be strings or unqualified keywords.


(defn valid-js-literal-key? [k]
  (or (string? k)
      (and (keyword? k)
           (nil? (namespace k)))))

2 Answers

+3 votes
edited by

Javascript literals are just JavaScript objects. Keys must be strings so there's little value in supporting keyword features. Really keywords in JS literals are just sugar for strings, it saves a character and looks Clojure-y at the cost of introducing some possible confusion about what is supported. So the main concern here would be introducing even more confusion - supporting namespaces would introduce certain expectations, i.e. namespace aliasing.

+1 vote
edited by

I'll just paste slack discussion here verbatim:

at least, lack of qualifier aliasing support:

dnolen [3:29 PM]
 @misha it's just not supported and it isn't going to be
you're not making maps
you're making JS literals
so little value in keyword stuff
dnolen [3:41 PM]
 `#js {:foo 1}` is identical to `#js {"foo" 1}`
there are no keywords
misha [3:41 PM]
 I was thinking about dev time "support", like using qualifiers to aid autocomplete, and narrow down keys set for a particular js obj I might build. So in source code it'd be e.g.`#js {:css/width 10}` and in js, ofc `{"width": 10}`
dnolen [3:42 PM]
 like I said there are no keywords, just strings
introducing namespacing brings along other expectations
misha [3:43 PM]
 well, allowing keywords there brought along my expectation :)
dnolen [3:43 PM]
 keywords aren't allowed
it's just a syntactical thing
misha [3:43 PM]
```cljs.user=> #js {:bar 1}
#js {:bar 1}```
dnolen [3:44 PM]
 I already explained this above
no keywords
when this was originally done as a surface syntax it was only for the convenience of saving a character
misha [3:44 PM]
 well, yes, I understand, that in js obj it'll be string. but I type in keyword on keyboard.
dnolen [3:45 PM]
 i.e. `#js {"bar" ...}`
@misha but you're misunderstand what I'm saying
real keywords do a bunch of things
misha [3:45 PM]
 I'm very glad that convenience is there
dnolen [3:45 PM]
 and have a lot of semantics
bringing anymore stuff just into `#js` isn't desirable
and your confusion shows that saving a keystroke was probably questionable design idea from one perspective (edited) 
anyways - no changes coming here - what's there is what's there
misha [3:49 PM]
 I would not say I am confused. It just seems to me that what I ask is the same as saving 1 char. I do not expect any qualified keyword semantics to get transferred to js obj. What I'm saying, is "there is a value in *typing in* qualified keyword because of IDE suggests assists" the same way there is a value in "saving a char" which is already there.
dnolen [3:49 PM]
 I understand quite clearly what you're saying, but I'm also explaining why it isn't a good idea
misha [3:49 PM]
 and I'm not asking for change. just wondering why that was explicitly prohibited.
dnolen [3:49 PM]
 I already explained that ^
misha [3:49 PM]
 you did, thank you (edited) 
dnolen [3:54 PM]
 @misha one typical read time thing that people might expect if you allow this is namespace aliasing
`#js {::foo/bar ...}`
no interest in supporting stuff like this
that is what you're proposing opens more questions
misha [3:56 PM]
 yeah, that's a very good example. thank you

and keys collision:

dpsutton  What would the canonical JavaScript representation of :ns/key be?
misha  @dpsutton there is none, I was asking from another point of view
dpsutton  i don't follow. but what is your suggestion for what `#js {:css/width 3}` would be?
misha  `{"width" 3}`
dpsutton  and what about `#js {:css/width 3 :panel/width 5}`
misha  {"width" 5}, or `Map literal contains duplicate key`
but good point