Fork me on GitHub
#cljs-dev
<
2018-05-28
>
mhuebert14:05:09

has there been any talk about supporting a plain ^js annotation for externs inference?

mhuebert14:05:08

I’ve been using this via shadow-cljs for a long time now and it’s really nice; I’d like to use it for libraries that can be :advanced compiled w/o shadow-cljs

thheller14:05:58

@mhuebert does it actually not work? it might just work?

mhuebert14:05:36

hmm I can check again. I thought I had run into a problem w/ this some months ago but my memory could be mistaken

mfikes14:05:33

It looks like, in that case, you get externs added to Object (along with a compiler warning that it is doing this)

mfikes14:05:52

WARNING: Adding extern to Object for property baz due to ambiguous expression (. x baz) at line 7 /Users/mfikes/Desktop/src/my_project/core.cljs
if you replace ^js/Foo.Bar with just ^js in the example at https://clojurescript.org/guides/externs

thheller14:05:51

but if you don't turn on the warnings it just works right?

mhuebert14:05:38

hmm I am trying to figure out why this “just works”, without annotation, and no warning is shown:

(ns js-test)

(set! *warn-on-infer* true)

(js* "window.x = {\"greeting\": \"Hello!\"} ")

(js/console.log "without annotation", (.. js/window -x -greeting))

thheller14:05:14

anything js/... just works

mhuebert14:05:30

including all sub-properties?

thheller14:05:52

not actually sure about CLJS itself but it should yes

thheller14:05:27

(.foo x) is the problem when x is "untyped"

mhuebert15:05:40

given:

(js/eval "function someObj () {return {\"greeting\": \"Hello!\"}};")  
works, with a warning: (no hint)
(println (.-greeting (js/someObj)))
does not work at all: (no hint, same thing but passed through a function)
(defn print-greeting [obj]
  (println (.-greeting obj)))
(print-greeting (js/someObj))
works, with a warning: (hint in arglist)
(defn print-greeting [^js obj]
  (println (.-greeting obj)))
(print-greeting (js/someObj))

thheller15:05:30

yes but if you do not (set! *warn-on-infer* true) it still generates the externs right?

thheller15:05:44

for the last and js/... cases

mhuebert15:05:30

yes I think so interesting, if I put some random non-^js thing as the hint, there is no warning, and it does not work:

(defn print-greeting [^someRandomHint obj]
  (println (.-greeting obj)))
(print-greeting (js/someObj))

thheller15:05:11

it assumes its a cljs/goog type and doesn't verify

thheller15:05:24

externs are only ever generated for js hints

mhuebert15:05:26

ok. so it looks like ^js does work wherever another js hint would work, just will print a warning when warnings are enabled

thheller15:05:51

yeah thats what I thought. since you don't need the set! in shadow-cljs that should be fine for your library then