I am porting a JavaScript library to Scalajs. The JS Objects are created with the new keyword on the JavaScript side, so this is what I do in most cases.
trait Point extends js.Object {
def normalize(length: Double): Point = js.native
}
This seems to work well for methods, however, this doesn't work for constructors.
@JSName("paper.Point")
object PointNative extends js.Object {
def apply(props: RectProps): Rectangle = js.native
}
The above code does not work. It passes type checks and compiles, but at runtime it returns undefined.
If I modified PointNative like this then all is good.
import js.Dynamic.{ global => g, newInstance => jsnew }
object PointNative {
def apply(props: RectProps): Rectangle = jsnew(g.paper.Point)(props).asInstanceOf[Point]
}
Is there a way to use @JSName and js.native with the new keyword?
Thanks!
Since, in the JavaScript API, paper.Point
needs to be instantiated with the new
keyword, you need to define PointNative as a class:
@JSName("paper.Point")
class PointNative(props: PointProps) extends js.Object {
...
}
which allows to instantiate it with
new PointNative(props)
just like you would have done in JavaScript.
If you also want to be able to instantiate it with just
PointNative(props)
then you need to define an additional, non-js.Object
companion with an apply()
method:
object PointNative {
def apply(props: PointProps): PointNative = new PointNative(props)
}
Note that, if you need the companion PointNative
to be a js.Object
(because you also want to define static methods of paper.Point
in it), then you can pimp apply()
on it with an implicit class instead:
implicit class PointNativeCompanionOps(val self: PointNative.type) extends AnyVal {
def apply(props: PointProps): PointNative = new PointNative(props)
}
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments