Does scalajs have a mechanism to 'upgrade' an object literal to a proper instance of a type?
As an illustration:
Given a simple type defined like:
import scala.scalajs.js
import scala.scalajs.js.annotation.JSExport
import scala.scalajs.js.annotation.ScalaJSDefined
@js.native
trait Point extends js.Object {
val x: Int = js.native
val y: Int = js.native
}
// or
@ScalaJSDefined @JSExport
class Point(val x: Int, val y: Int) extends js.Object
and some function to use it:
import scala.scalajs.js.annotation.JSExport
@JSExport
object Foo {
@JSExport
def foo(point: Point) = ???
}
From the javascript environment, I want to be able to 'upgrade' an equivalent object literal value to be a proper Point
instance, so the following behavior is the same:
var p1 = new Point(1, 1);
Foo.foo(p1);
var p2 = { x: 1, y: 1 };
Foo.foo(p2);
What is the best way to achieve this?
First, assuming your first definition of Point
, ie,
@js.native
trait Point extends js.Object {
val x: Int = js.native
val y: Int = js.native
}
an object literal { x: 1, y: 1 }
already is a valid instance of Point
. It would also be better to use a Scala.js-defined JS trait rather than a native trait:
@ScalaJSDefined
trait Point extends js.Object {
val x: Int
val y: Int
}
If you use your other definition of Point
, ie,
@ScalaJSDefined @JSExport
class Point(val x: Int, val y: Int) extends js.Object
then the best way is to also define a PointJS
that is a JS trait, and implicit conversions to/from Point
:
@ScalaJSDefined
trait PointJS extends js.Object {
val x: Int
val y: Int
}
object PointJS {
implicit def point2pointJS(p: Point): PointJS = new PointJS {
val x = p.x
val y = p.y
}
implicit def pointJS2point(p: PointJS): Point =
Point(p.x, p.y)
}
and then, you will need a JS-friendly export, which uses a PointJS
and not a Point
:
@JSExport
object Foo {
@JSExport
def foo(point: Point) = ???
@JSExport
def foo(point: PointJS) = foo(point: Point)
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.