2017-07-19 103 views
1

假設我有這個定義在Scala.js一些庫函數的返回類型我使用:在Scala.js中,如何最好地創建一個符合JS外觀特徵的對象?

@native 
trait Link extends Object { 
    val href: String = native 
    val title: String = native 
} 

什麼是最好的,類型安全的方式,在Scala代碼,定義一個對象字面貼合對此?我以爲use(...).as[...]伎倆將工作:

val link = js.use(new { 
    val href = "value1" 
    val title = "value2" 
}).as[Link] 

但是,這產生了錯誤:

AnyRef{val href: String; val title: String} does not export a getter href: String

爲什麼?

我也試過這個,並且如預期失敗:

val link = js.use(js.Dynamic.literal(
    href = cap(2), 
    title = cap(3) 
)).as[Link] 

scala.scalajs.js.Object with scala.scalajs.js.Dynamic does not have a getter href: String

最後,我也試過這樣:

val link = new Link { 
    override val href = "value1" 
    override val title = "value2" 
} 

,並得到

A Scala.js-defined JS class cannot directly extend a native JS trait

現在,我這樣做:

val link = js.Dynamic.literal(
    href = "value1", 
    title = "value2" 
).asInstanceOf[Link] 

這工作,但它不是由編譯器檢查,如果我沒有記錯。

回答

2

圖書館應聲明Link@ScalaJSDefined而不是@js.native。這可以讓你做第三個變種(new Link { ... }),我建議你爲這個庫提交一個bug報告。

作爲一種解決方法,你可以使用.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] 
+0

謝謝你,我誰錯寫的外觀類型的一個那麼什麼是有史以來定義'@ js.native'特質,而不是'@ ScalaJSDefined'性狀優勢這種情況下? –

+0

在這種情況下,沒有。對於traits,如果沒有其他選擇(例如,因爲它包含'apply'方法),只將它們定義爲'@ js.native'。 – sjrd

相關問題