如何将 JavaScript 对象转换为 Kotlin 对象?

How do I cast a JavaScript object to a Kotlin object?

我收到了一个 JavaScript 对象来响应远程 HTTP 请求。我有一个 kotlin 模型(特征),它定义了我期望在对象上的各个字段(可为空的字段是可选的)。

首先,我想进行 is 检查以确保我的对象实际上是预期的类型。我最初尝试 payload is MyModel 但由于 is 运算符在 kotlin.js.

中的编写方式,这不起作用

其次,我想转换为 MyModel,这样我就可以在处理对象时自动完成等。通常,单独使用 is 就足够了,但由于这不起作用,我也需要一些东西来解决这个问题。

我想避免从 dynamic 手动填充我的对象。如果我可以使用 by Delegates.mapVal(...) 我不介意做这么多,但这需要 Map<String, Any?> 而且我不知道如何将我的 dynamic/Any? 有效负载放入Map<String, Any?>.

对于第二部分,演员,你可以这样做:

fun responseHandler(payload: dynamic) {
    val myModel = payload as MyModel
}

fun responseHandler(payload: dynamic) {
    val myModel: MyModel = payload
}

如果有效载荷为空,这将抛出 NPE,但实际上不会验证有效载荷是否与 MyModel 匹配。特别是,如果有效负载缺少那些 fields/properties.

,您可能最终会得到 null fields/properties

1) 由于性能原因,我们没有对 is 进行结构检查。 我不确定我们是否需要通用解决方案,但无论如何我创建了 issue about it,请随意投票或加注星标以获取更新。

2) is 如果你使用 smart cast 就足够了,比如:

if (payload is MyModel) {
// call MyModel members on payload
}

但不要忘记 (1) :)

3) 你可以这样写:

class MapDynamic<out V>(val d: dynamic) {
  public fun get(thisRef: Any, desc: PropertyMetadata): V {
        return d[desc.name]
    }
}

class Foo(data: dynamic) {
  val field: Int by MapDynamic(data)
}

fun main(args : Array<String>) {
  val f = Foo(object { val field = 123 })
  println(f.field)
}

但它看起来太冗长了,但是你可以添加额外的逻辑,例如当数据没有请求的字段时。如果您不需要自定义逻辑,我认为强制转换就足够了。