In progress - an explanation of the ClojureScript type system
The main idea is that a type can either be reprsented by a symbol, like number or string, or a set, like #{number string}. The latter means that the value set includes all numbers and strings.
These type symbols are the same ones used in tag meta, as in ^number, which expands to {:tag number}
The type of the value nil is the symbol clj-nil (as opposed to (symbol "nil"))
If you see nil as a type, this means the type wasn't infered.
The special type seq is used to represent the reqturn type of the seq function, essentially representing either clj-nil or any non-empty sequence.
The special type any is satisfied by any value.
Arguably
anyandnilhave similar semantics. One explicitly means any type, while the other means an unknown type (which could be more narrow thanany, but is simply not known).
JavaScript types look like js/Foo. The special type js means any JavaScript value.
The type of a deftype or defrecord will look like a qualified symbol cljs.user/Bar, or cljs.core/Keyword.
A type can be "canonicalized": The type #{number} can be simplified / canonicalized to number.
The type #{clj-nil seq} will be simplified / canonicalized to seq.
A type involving any can be canonicalized to just any: #{number any} can be reduced to any.
TBD: Explain not-native, clj