Jea*_*let 2 casting object-literal type-safety scala.js
假设我在Scala.js中具有此定义,用于我正在使用的某些库的函数的返回类型:
@native
trait Link extends Object {
val href: String = native
val title: String = native
}
Run Code Online (Sandbox Code Playgroud)
在Scala代码中,定义符合此要求的对象文字的最佳,类型安全的方法是什么?我认为这个use(...).as[...]技巧会起作用:
val link = js.use(new {
val href = "value1"
val title = "value2"
}).as[Link]
Run Code Online (Sandbox Code Playgroud)
但这会产生错误:
AnyRef {val href:字符串;val title:String}不会导出getter href:String
为什么?
我也尝试过此方法,并且按预期失败了:
val link = js.use(js.Dynamic.literal(
href = cap(2),
title = cap(3)
)).as[Link]
Run Code Online (Sandbox Code Playgroud)
给
具有scala.scalajs.js.Dynamic的scala.scalajs.js.Object没有getter href:字符串
最后,我还尝试了以下方法:
val link = new Link {
override val href = "value1"
override val title = "value2"
}
Run Code Online (Sandbox Code Playgroud)
并得到
Scala.js定义的JS类无法直接扩展本机JS特性
现在,我正在这样做:
val link = js.Dynamic.literal(
href = "value1",
title = "value2"
).asInstanceOf[Link]
Run Code Online (Sandbox Code Playgroud)
这可行,但是如果我没记错的话,编译器不会检查它。
库应声明Link为,@ScalaJSDefined而不是@js.native。这将允许您执行第三个变体(带有的变体new Link { ... }。我建议您为该库提交错误报告。
解决方法是,要么对进行操作.asInstanceOf[Link],要么,如果需要js.use(x).as[T]安全,请使用以下方法:
@ScalaJSDefined
trait LinkImpl extends js.Object {
val href: String
val title: String
}
val link = js.use(new LinkImpl {
val href = "value1"
val title = "value2"
}).as[Link]
Run Code Online (Sandbox Code Playgroud)