Как сгенерировать JavaScript-функцию с `this.field=value` в теле, в KotlinJs

Когда я использую KotlinJS с бунтом, для определения тега требуется функция, подобная следующей:

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!"
    }
}

Хотя я могу написать код Kotlin так:

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!"
    }
}

Но вы можете видеть, что у него есть несколько проблем:

  1. Мы должны использовать некоторые js("this") трюки
  2. self.name, self.messageи тому подобное, во всем теле функции много динамического кода

Как их избежать? Я хочу написать как можно больше чистого, безопасного для типов кода Kotlin.

И, заранее, можно ли определить класс, который имеет более четкую структуру, например:

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

Я могу согласиться сделать некоторые преобразования против класса, чтобы сгенерировать требуемую функцию.

1 ответ

Решение

Возможное решение может быть брошено js("this") известному котлинскому типу. Хоть 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!" }
}
Другие вопросы по тегам