https://kotlinlang.org logo
#javascript
Title
# javascript
s

Seth Madison

03/19/2023, 2:25 AM
I wish there was a way to define an external interface that conforms to a normal interface. It feels like it could be done with an annotation or something that you put on a normal interface that tells the compiler not to expect getters.
t

turansky

03/19/2023, 4:29 PM
Normal - your custom interface?
s

Seth Madison

03/19/2023, 5:39 PM
Imagine:
Copy code
interface FooCommon {
    val bar: String
}
I want to be able to do:
Copy code
external interface FooJs : FooCommon {
    val bar: String
}

fun parseJs(): FooCommon {
    val myDynamic = js("""{bar: "baz"}""")
    return myDynamic.unsafeCast<FooJs>()
}
Instead I have to do something like;
Copy code
external interface FooJs {
    val bar: String
}


class FooCommonFromJs(private val fooJs: FooJs) : FooCommon {
    override val bar: String
        get() = fooJs.bar
}

fun parseJs(): FooCommon {
    val myDynamic = js("""{bar: "baz"}""")
    return FooCommonFromJs(myDynamic.unsafeCast<FooJs>())
}
t

turansky

03/19/2023, 6:53 PM
We have
jso
for such cases
Expected implementation:
Copy code
fun parseJs(): FooCommon =
    jso {
       bar = "baz"
    }
s

Seth Madison

03/20/2023, 3:34 AM
Ah, interesting I did not know about
jso
. It looks like it just casts whatever you pass as the type param, which I think is the equivalent of:
Copy code
fun parseJs(): FooCommon {
    val myDynamic = js("""{bar: "baz"}""")
    return myDynamic.unsafeCast<FooCommon>()
}
Originally I tried this:
Copy code
fun parseJs() {
    val myDynamic = js("""{bar: "baz"}""")
    val a = myDynamic.unsafeCast<FooCommon>()
    console.log(a.bar)
}
And it didn’t work because
FooCommon
was not
@JsExported
!!! It turns out, if you
@JsExport
a “normal” class, it forces the compiler to not generate JS properties that mirror the kotlin property names, and so an
unsafeCast()
will “just work”.
So, for posterity, I think the solution here is:
Copy code
@JsExport
interface FooCommon {
    val bar: String
}


fun parseJs(): FooCommon {
    val myDynamic = js("""{bar: "baz"}""")
    return myDynamic.unsafeCast<FooCommon>()
}
t

turansky

03/20/2023, 7:03 AM
jso
recommended in any case
in future Kotlin is see following variant:
Copy code
@JsExport
@ExternalInJsPleas
interface FooCommon {
    val bar: String
}


fun parseJs(): FooCommon {
   FooCommon(bar = "baz")
}
3 Views