简体   繁体   中英

Upgrade object literal to proper class instance in ScalaJS?

Does 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM