Fork me on GitHub
#clojurescript
<
2022-09-27
>
shaunlebron17:09:47

Can ^js be used in place of ^js/React.Element ? I saw this question come up here (https://github.com/lilactown/helix/pull/104#discussion_r955408172), and I’d like to document this in the cljs api docs so people can just search ^js and have a canonical description. Please let me know your thoughts!

thheller17:09:53

^js is the simplified type hint method that has the same effect as the typed variant yes

thheller17:09:11

technically the externs are less precise but that would only be relevant if all code is properly typed

👍 1
shaunlebron17:09:59

I read the blog post on externs inference that had the full form, and saw that you answered that the full form isn’t needed. I guess this requires understanding why externs can omit the full form? I don’t quite understand.

shaunlebron17:09:39

To be sure, ^js isn’t shadow-specific right?

thheller17:09:30

not actually sure 😛 the cljs default used to warn about ^js adding extern properties to the generic object. dunno if it still does that

thheller17:09:50

but it definitily does work just fine with regular cljs

shaunlebron17:09:45

I did some searching here and saw @U2FRKM4TW say that the compiled code is the same for both ^js and ^js/React.Element, so the difference must be in the externs file creation unless the compiler throws away the type completely.

thheller17:09:56

shadow-cljs throws it away. the regular compiler uses it. but as I explained in the blog post the closure-compiler doesn't actually use it unless all related code is fully typed

shaunlebron17:09:07

ah I see, so the full form effectively just documents the expected type

shaunlebron17:09:05

Thanks! I’ll write a quick entry and post a link here when done.

shaunlebron17:09:34

@U05224H0W can you say more about the ^clj and ^goog tags you mentioned on the blog post?

thheller17:09:04

they aren't actual tags that have any meaning. they just serve to shut up externs inference without generating any externs

shaunlebron17:09:56

shadow-specific?

thheller17:09:20

not really. externs inference just won't warn if the code is hinted. as far as cljs is concerned there is a tag it doesn't know, so doesn't do anything with it

thheller17:09:50

its not official, but it works

thheller17:09:25

shadow has no extra code related to this

thheller17:09:25

but yes, thats where most externs inference happens

shaunlebron17:09:44

it looks like (when (not= 'js target-tag) …) is what causes ^js to be abbreviated without full class name

thheller17:09:47

thats just warnings

shaunlebron17:09:01

what is the tag meta prefix?

shaunlebron18:09:42

Okay, I think this is all I need to know right here: https://github.com/clojure/clojurescript/blob/40358fc4c53090676da82e3f4c52920003678902/src/main/clojure/cljs/analyzer.cljc#L3491-L3496^js adds externs properties on Object^js/React.Element adds externs properties on React.Element.prototype

thheller18:09:42

correct. although important to know that unless 100% of the code is typed it doesn't matter whether its on object or react.element

shaunlebron18:09:35

right. but wait, I don’t get how that still wouldn’t trigger the warning here for Object property access: https://github.com/clojure/clojurescript/blob/40358fc4c53090676da82e3f4c52920003678902/src/main/clojure/cljs/analyzer.cljc#L3500-L3503

shaunlebron18:09:28

I think most people are using shadow-cljs these days lol

thheller18:09:25

in regular cljs you have to (set! *warn-on-infer* true) in your code to actually get any warnings

thheller18:09:58

not a whole lot of people do that I guess, so they don't get any warnings at all for inference

👍 1
thheller18:09:14

shadow just added the auto part that automatically enables the warnings for your source files

shaunlebron18:09:19

oh my bad, I’m forgetting that the point here is to just write externs and not avoid warnings

thheller18:09:37

guess shadow-cljs is to blame for that 😉

shaunlebron18:09:26

ha, I thought it was for official cljs too. from the implementation, I can see how it would stop the warnings if they were on

thheller19:09:49

^clj might have an official meaning. I actually do not know 😛

thheller05:09:18

I feel like the table showing where the externs are added is more confusing than helping there

👀 1
henryw37412:09:34

thanks. I hadn't noticed that @U050B88UR had commented on that bug, saying it's not a big issue. It bothers me that someone could correctly follow an official guide like http://cljs.github.io/api/syntax/js-tag and find their code not run. @U061E2UBT if you're able to make edits, could you update the https://cljs.github.io/api/syntax/dot entry to carry a health warning where it talks about foo.bar.baz style?

👍 1
shaunlebron14:09:06

@U051B9FU1 done, thanks!

🎉 1
❤️ 1
shaunlebron14:09:16

@U05224H0W I got rid of the ugly table. I think it works as a bullet list instead

thheller15:09:40

not sure that helps either. I mean you kinda need in depth understanding of what externs are and how they work to understand the difference there?

thheller15:09:17

for example shadow-cljs generates ShadowJS hints since the function that "provides" JS types is tagged with it. so, the closure compiler will see the returned types as all ShadowJS. https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/js.js#L25-L28

thheller15:09:44

overall that doesn't matter at all since most other code isn't type hinted, but thats the reason for ShadowJS and not Object. when it comes to the end result that would be identical, but there is a thought behind it

thheller15:09:54

nobody ever needs to care though 😛

thheller16:09:21

my summary would be that the property is added to externs and as such prevents any renaming of that property name

thheller16:09:36

what it is added to really doesn't matter for CLJS, only in fully typed code

🙏 1
shaunlebron16:09:56

great, I’ll write that in