Как сгенерировать 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!"
}
}
Но вы можете видеть, что у него есть несколько проблем:
- Мы должны использовать некоторые
js("this")
трюки 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!" }
}