如何从伪联合类型中提取正确的类型

use*_*729 2 scala.js

我有一个从 js 返回的伪联合类型。

这是我的 scalajs:

    @js.native
    特征 ErrorResponse 扩展 js.Object {
      val错误:字符串= js.native
      val 错误描述:String = js.native
    }

    @js.native
    特征 TokenResponse 扩展 js.Object{
      val accessToken: String = js.native
      val expriseOn: js.Date = js.native
      val tokenType: String = js.native
      val userId: String = js.native
      val IdentityProvider: String = js.native
    }

和我的 scalajs

    @js.native
    @JSImport("mymodule", "JSClassInModule")
    JSClassInModule 类扩展 js.Object {
      // ...
      def scalajsfunc(): 错误响应 | TokenResponse = js.native
      // ..
    }

如果我调用 scalajsfunc,如何惯用地将返回值归结为伪联合类中指定的两个类之一?

sjr*_*jrd 6

使用模式匹配:

val jsClassInModule: JSClassInModule = ???
(jsClassInModule.scalajsfunc(): Any) match {
  case response: ErrorResponse => ...
  case response: TokenResponse => ...
}
Run Code Online (Sandbox Code Playgroud)

该归属: Any对于解决以下事实是必要的:Scala 类型检查器不知道 的具体语义|,并且如果您尝试直接匹配|.

编辑:如果单个类型是JS Traits,即扩展的 Traits js.Any,则上述方法将不起作用,因为通常不可能使用isInstanceOfJS Traits 执行测试(这是模式匹配的作用,并且大多与 无关|)。相反,您需要对任何有意义的实例测试进行编码,然后进行强制转换。例如,假设我们可以通过测试属性的存在来区分 anErrorResponse和 a ,我们可以这样做:TokenResponseerrorCode

val jsClassInModule: JSClassInModule = ???
(jsClassInModule.scalajsfunc(): Any) match {
  case response if js.Object.hasOwnProperty(response, "errorCode") =>
    val errorResponse = response.asInstanceOf[ErrorResponse]
    ...
  case response =>
    val tokenResponse = response.asInstanceOf[TokenResponse]
    ...
}
Run Code Online (Sandbox Code Playgroud)

这就是 JavaScript 丑陋的本质。