In building the web frontend for Outboard, I am using Apple’s MapKit JS, which is delivered via CDN and not included in my application’s bundle locally. Under ClojureScript’s advanced compilation, this means there are places where type hinting for externs is necessary.

My code initially looked like this:

(go
  (let [map (js/mapkit.Map. "map-element")
        ; ...
        annotation (<! (fetch-annotation))]
        ; ...
        (.addAnnotation map annotation)))

This resulted in an error “Cannot infer target type in expression” from the compiler, so I type-hinted the map:

(go
  (let [^js/mapkit.Map. map (js/mapkit.Map. "map-element")
        ; ...
        ] ;...))

Same error. I then extracted the annotating code to a function, where I could type-hint the map:

(defn add-annotation
  [^js/mapkit.Map map annotation]
  (.addAnnotation map annotation))

This worked, but seemed odd to me; the documentation on type-hinting doesn’t say there’s anything different between a let block and a function argument.

When I checked in on Clojurians Slack, Thomas Heller confirmed to me that this is a bug with core.async, where type information in a let block can get lost. Since this was difficult for me to find much documentation on anywhere (and type-hinting in ClojureScript itself is very lightly documented), hopefully spelling out this experience here can save someone some frustration in the future.