Anyone had any success with using typescript's awa...
# javascript
a
Anyone had any success with using typescript's await to call a function implemented in Kotlin/JS?
c
I believe
await
in JS/TS is just syntactic sugar over a Promise, so you should be ableto return a
Promise<T>
(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.js/-promise/) from Kotlin to be able to
await
it from TS. You likely can’t
await
a
suspend
Kotlin function
a
Thanks for the quick response 🙂 yes, I'm attempting to do just that
the problem seems to be that the .d.ts definitions generated by the IR compiler have my functions returning kotlin.js.Promise, which TypeScript has no sugar for
r
a
ha - thanks 🙂
My little experiment with kotlin and typescript seems to be running into a few of those!
Any known workaround for this, other than hand-rolling (or editing) my own .d.ts files?
c
What happens if you convert it to a
dynamic
type instead of
Promise
?
a
actually, that works - good suggestion! 🙂
🎉 1
Unfortunately, the object that comes back is mangled beyond use by other bugs - but the promise is unwrapped!
If I have an unexported kotlin class that implements an exported interface, the class name and property names are mangled by the IR and cannot be addressed via the names exported to my .d.ts file.
The class cannot be exported because of a bug that prevents
@JsExport
and
@Serializable
on the same class.
Implementing the exported interface seemed like an elegant workaround, but I guess I will have to try having two classes - one serializable and the other exported, then copying the data between them.
a
@adk Could you maybe use @JsName in the class to work around that and prevent mangling on the class?
a
@ankushg Unfortunately that's not allowed. You can't use JsName in a non-exported class and you can't export a serialisable class.
So, it turns out that the IR compiler generates all JS code with underscores prefixing member names. Properties of exported classes have properties added to the prototype to map between the JS variable and the declared/exported member name, but if you export an interface, but not its implementation class, then that mapping does not occur.
Falling back to `JsExport`ing one class, while having a Serializable copy of the class for internal use works.
a
Interesting -- would love to see an example. JsExport + Serialization issues are one of our biggest blocker for trying out IR
a
Unfortunately I can't make the code public, but the approach is very straightforward. Simply copy/paste your data class and replace
@JsExport
with
@Serializable
.
For context, I am doing this as part of a spike to investigate whether Kotlin multiplatform with TypeScript via the IR compiler can be of use to us. There have been quite a few hoops to jump through to get it working - this little hack being only the latest of them.
Having only one place to maintain your domain model for different clients of your API is quite a powerful feature, but you have to be pretty determined to get it working - and willing to sacrifice a bit of elegance in your code. The remaining step in my spike is to work out to what extent I can encapsulate the ugliness to produce an API that both typescript and JVM developers will be happy to consume. I suspect we may choose to wait a bit before any actual adoption.