带有 JS 和应用程序数据的 ScalaJS 门面

ScalaJS facades with JS and application data

我正在尝试为 jQuery 插件 (https://github.com/devbridge/jQuery-Autocomplete) 编写外观。其中包括一些传递我建模为的对象的回调:

@js.native
trait AutocompleteSuggestion extends js.Object {
  val value: String = js.native
  val data : js.Any = js.native
}

图书馆需要访问valuedata 供我使用。我创建对象,将其提供给库,然后它作为回调的参数返回给我。

我为创建这些对象所能做的最好的是

object AutocompleteSuggestion {
  def apply[T](value: String, data: T) = {
    literal(value = value, data = data.asInstanceOf[js.Any]).asInstanceOf[AutocompleteSuggestion]
  }
}

传递给这些对象之一的回调通常最终看起来像

def onSelect(suggestion: AutocompleteSuggestion): Unit = {
  val cb = suggestion.data.asInstanceOf[CourseBasic]
  // do something with the data
}

有什么改进建议吗?特别是感觉我在做很多选角。我在 https://www.scala-js.org/doc/interoperability/facade-types.html 的例子中没有看到这一点——但这些例子也刻意避免使用原始类型以外的任何东西。

我建议如下。基本上它归结为通过为 data 的类型提供类型参数来更好地键入 AutocompleteSuggestion。此外,我们将它设为 @ScalaJSDefined trait 而不是 @js.native(无论如何大多数 JS trait 都应该如此),以便我们可以以类型安全的方式实例化它:

import js.annotation._

@ScalaJSDefined
trait AutocompleteSuggestion[T] extends js.Object {
  val value: String
  val data: T
}

object AutocompleteSuggestion {
  def apply[T](value0: String, data0: T): AutocompleteSuggestion[T] = {
    new AutocompleteSuggestion[T] {
      val value: String = value0
      val data: T = data0
    }
  }
}

def onSelect(suggestion: AutocompleteSuggestion[CourseBasic]): Unit = {
  val cb = suggestion.data
  // do something with the data
}

Aaand, 不是一个演员:)