I've been practicing leveraging as much JVM code as possible in Scala.JS in order to benefit from unit testing pure JVM logic, which is of course much faster. At some point though, you run into the issue where the function you'd like to implement in the JVM cannot be written without passing a JS object to it, even if you do not call any methods of this object (it's effectively an AnyRef for all intents and purposes).
For instance, in a React JS application, maybe you have some if/else logic for deciding which components to return from your JVM function in order for React to render. The components are just objects (AnyRef) as far as the JVM is concerned, but on the JS side they need to be upcasted back to component types:
I'm naively solving this using:
// convert to AnyRef at compile-time before passing to a JVM function:
type Jvm = AnyRef
def toJvm(elements: ReactElement*): Seq[Jvm] = elements : Seq[Jvm]
Then your JVM function decides which to render:
def whichToRender(isDayTime: Boolean, jvm: Seq[Jvm]): Seq[Jvm] = {
if (isDayTime) {
Seq(jvm.head)
} else {
Seq.empty[Jvm]
}
}
But the downside is in order to convert back to JS, I must use asInstanceOf, which suffers a runtime cost:
def toJs(elements: Seq[Jvm]): Seq[ReactElement] = elements.asInstanceOf[Seq[ReactElement]]
So is there anyway to hide the underlying type of the React Component so that the JVM just Sees an Object but the underlying type is still recoverable, at compile-time to avoid runtime cost with type casting?
AnyRef?asInstanceOfonce you're in fullLink mode. Also, there is no run-time cost toasInstanceOfwhen the target type is a JS type.