0

When I use KotlinJS with riot, it requires a function like following to define a tag:

function (opts) {
    var self = this
    self.name = "sample"
    self.message = "init-message"

    self.onCreate = fun(opts: dynamic) {
        self.message = opts.message
    }

    self.click = fun() {
        self.message = "Clicked!"
    }
}

Though I can write the Kotlin code like this:

fun(opts: dynamic) {
    val self = js("this")

    self.name = "sample"
    self.message = "init-message"

    self.onCreate = fun(opts: dynamic) {
        self.message = opts.message
    }

    self.click = fun() {
        self.message = "Clicked!"
    }
}

But you can see it has several problems:

  1. We have to use some js("this") tricks
  2. self.name, self.message, and similar, there are a lot of dynamic code all over the function body

How to avoid them? I want to write pure, type-safe Kotlin code as much as possible.

And, in advance, is it possible to define a class which has clearer structure, like:

class MyTag {
   val name = "sample"
   var message = "init-message"
   fun onCreate() {}
   fun click() {}
}

I can accept to do some conversions against the class to generate the required function.

4

1 回答 1

1

可能的解决方案可能会js("this")转换为已知的 kotlin 类型。尽管js()仍然存在,但它的用法非常本地化,并且代码实际上是类型安全的。

下面的代码产生了你在 js 中需要的东西

interface MyTag {
    var name: String

    var message: String

    var onCreate: (dynamic) -> Unit

    var click: () -> Unit
}

inline fun <T> builder(block: T.() -> Unit) = block(js("this"))

fun tagFunction(opts: dynamic) = builder<MyTag> {
    name = "sample"

    message = "init-message"

    onCreate = { message = opts.message }

    click = { message = "Clicked!" }
}
于 2018-04-11T16:21:42.823 回答