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:
js("this")
tricksself.name
, self.message
, and similar, there are a lot of dynamic code all over the function bodyHow 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.
The possible solution might be cast js("this")
to known kotlin type.
Though js()
still exists its usage is very local and code actually type-safe.
The code bellow produces what you need in 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!" }
}