Seth Madison
03/19/2024, 4:36 AMexternal interface
of the args to allow for js-style object arguments? I’m imagining:
@JsConstructor
@JsExport
data class ImportantData(foo: String, bar: Int)
Would end up generating JS-only code like:
external interface ImportantDataArgs {
val foo: String
val bar: Int
}
inline fun createImportantData(args: ImportantDataArgs): ImportantData {
return ImportantData(foo = args.foo, bar = args.bar)
}
That would ultimately generate a JS function that would be typed so that you could do:
createImportantData({
foo: "hello",
bar: 123
});
Does something like this already exist?Edoardo Luppi
03/19/2024, 8:43 AMjso { ... }
for that last snippet to work.Artem Kobzar
03/19/2024, 8:44 AMjs-plain-objects
: https://github.com/JetBrains/kotlin/tree/master/plugins/js-plain-objects
So, your code will look like:
@JsPlainObject
external interface ImportantDataArgs {
val foo: String
val bar: Int
}
fun main() {
val args = ImportantDataArgs(foo = "hello", bar = 123) // just a regular js object
println(JSON.stringify(args)) // { foo: "hello", bar: 123 }
}
Unfortunately, it works only with K2.Edoardo Luppi
03/19/2024, 8:49 AMconst x = {
one: 1,
two: 2,
}
You can do it with the external interface and the jso
helper function
val x = jso<ImportantDataArgs> {
one = 1
two = 2
}
Although, I find this not idiomatic to Kotlin, and I'd prefer the plain object solution that is implemented for K2.Edoardo Luppi
03/19/2024, 8:53 AMArtem Kobzar
03/19/2024, 8:57 AM@JsPlainObject
does. It compiles to exact JS object:
// Kotlin
val args = ImportantDataArgs(foo = "hello", bar = 123)
// JavaScript
var args = { foo: "hello", bar: 123 }
CLOVIS
03/19/2024, 10:26 AMcreateImportantData(jso {
foo = "hello"
bar = 123
});
Sure, it's not exactly the same syntax, but it's fine, no?CLOVIS
03/19/2024, 10:32 AMEdoardo Luppi
03/19/2024, 10:49 AMCLOVIS
03/19/2024, 10:49 AMSeth Madison
03/19/2024, 11:45 AMconst important = createImportantData({
foo: "hello",
bar: 123
});
Instead of what they have to do today which is:
const important = new ImportantData("hello", 123)
Does that make more sense?CLOVIS
03/19/2024, 12:13 PMSeth Madison
03/19/2024, 4:41 PMEdoardo Luppi
03/19/2024, 4:45 PMCLOVIS
04/13/2024, 8:12 PMSeth Madison
04/14/2024, 3:33 AMhfhbd
04/15/2024, 12:51 PMhfhbd
04/15/2024, 12:56 PM@JsPlainObject
external interface InputOptions {
var required: Boolean?
var trimWhitespace: Boolean?
}
I enabled the plugin in my library as well as in the consumer project but I get this JS code: InputOptions;
throwLinkageError("Function 'invoke' can not be called: No function found for symbol 'com.github.actions/InputOptions.Companion.invoke|invoke(kotlin.Boolean?;kotlin.Boolean?){}[0]'");
Edoardo Luppi
04/15/2024, 1:28 PMEdoardo Luppi
04/16/2024, 12:06 PMhfhbd
04/16/2024, 12:07 PMArtem Kobzar
04/16/2024, 2:14 PMJsPlainObject
annotation, so, its is not required to apply the plugin on the consumer side (Edoardo Luppi
04/16/2024, 2:15 PMArtem Kobzar
04/16/2024, 2:16 PMEdoardo Luppi
04/16/2024, 2:17 PMArtem Kobzar
04/16/2024, 2:17 PMArtem Kobzar
04/19/2024, 12:09 PMArtem Kobzar
05/03/2024, 1:00 PMhfhbd
05/03/2024, 1:11 PMEdoardo Luppi
05/03/2024, 1:12 PMEdoardo Luppi
05/03/2024, 1:12 PMhfhbd
05/03/2024, 1:13 PMEdoardo Luppi
05/03/2024, 1:14 PMhfhbd
05/03/2024, 1:14 PMCasey Morris
07/08/2024, 9:52 PM@JsNamedArgs
annotation: https://github.com/PhiloInc/JsNamedArgs
This annotation and compiler plugin codegens external interfaces and new functions that accept the interface as an input, all of which is then exported to JS. This has made things a bit easier for our JS developers to use our KMP library! Hope it can help other as well!Edoardo Luppi
07/08/2024, 9:57 PM