这始于与David Nolen在Slack上的讨论,见https://clojurians.slack.com/archives/C07UQ678E/p1644422895167709
现在似乎越来越流行,在需要编译器警告用户“无法推断目标类型”的地方,依赖于JS交互语法加上^js
。同时,也不罕见使用内置CLJS函数和宏如first
、seq
、when-first
等在JS对象和数组上 - 毕竟,它们对此有明确的支持。
这导致了一个问题,使得它极其容易在优化构建中引入问题,而这些问题的预防是根本不可能的,除非你在做JS交互的地方到处都使用^js
。
这对于交互大量的代码来说尤其正确,例如下面这个例子
(defn replace-track-source! [^js playlist track-name src]
(loop [tracks (.-tracks playlist)]
(when-first [^js track tracks]
(if (= (.-name track) track-name)
(-> (to-audio-buffer src playlist)
(.then (fn [audio-buffer]
(let [audio-buffer (audio-util/normalize-volume audio-buffer)]
(set! track -src audio-buffer)
(.setBuffer track audio-buffer)
(.setCues track 0 (.-duration audio-buffer))
(.setPlayout track (doto (Playout. (.-ac playlist) audio-buffer)
(.setVolumeGainLevel (.-gain track))
(.setStereoPanValue (.-stereoPan track))))
(.calculatePeaks track (.-samplesPerPixel playlist) (.-sampleRate playlist))
(.adjustDuration playlist)
(.drawRequest playlist)))))
(recur (next tracks))))))
上面的例子有问题,因为编译器在您删除前面track
绑定的^js
时不会警告您。但是,没有这个标签,所有在track
上调用的函数的名字都将被压缩。
一个可能的解决方案是在CLJS函数在JS对象/数组上使用时不保留^js
标签时,引入一个选定的警告。