Daan
11/13/2020, 11:01 PMlibraryFunction({ optionalArg1: 'value', optionalArg2: true });
So far, I've been using this utility function:
fun <T> obj(block: T.() -> Unit): T =
js("{}").unsafeCast<T>().apply(block)
Which can be used like this:
libraryFunction(obj { optionalArg1 = "value"; optionalArg2 = true })
Given the following external declarations:
external interface Args {
optionalArg1: String
optionalArg2: Boolean
}
external fun libraryFunction(args: Args)
Daan
11/13/2020, 11:06 PMVampire
11/13/2020, 11:07 PMVampire
11/13/2020, 11:08 PMDaan
11/13/2020, 11:10 PMVampire
11/13/2020, 11:12 PMorg.jetbrains:kotlin-extensions
Daan
11/13/2020, 11:16 PMMarc Knaup
11/14/2020, 1:15 AMjson("optionalArg1" to "value", "optionalArg2" to true).asDynamic()
Daan
11/14/2020, 12:12 PMSvyatoslav Kuzmich [JB]
11/14/2020, 2:10 PMlibraryFunction(object : Args {
override optionalArg1 = "value"
override optionalArg2 = true
})
If you use this method a lot, and this verbose syntax is all over the place, you can create a trivial class that implements this Args
interface, or if possible, wrap this libraryFunction
with a function with idiomatic Kotlin signature with default arguments:
fun wrappedLibraryFunction(
optionalArg1: String? = undefined,
optionalArg2: Boolean? = undefined,
): Args =
object : Args {
override optionalArg1 = optionalArg1
override optionalArg2 = optionalArg2
}
… you don’t have to implement an entire interface that might contain dozens of properties of which you only really need 2 or 3. You also can’t know which ones are required by reading the kotlin external declarations (but you can document this of course).External interface you are using can be improved! With “default getter interface implementation” you don’t need to implement every member. Definitely helps with a dozen default members you don’t care about. This way default arguments are not only documented (in a bit weird way, but still) but are also enforced by type system.
external interface Args {
val optionalArg1: String?
get() = definedExternally
val optionalArg2: Boolean?
get() = definedExternally
}
...
// all defaults!
libraryFunction(object : Args {})
Are you getting externals from dukat?Daan
11/14/2020, 2:14 PMDaan
11/14/2020, 2:15 PMSvyatoslav Kuzmich [JB]
11/14/2020, 2:20 PMobject : <external-ifaces> { <overrides-of-external-interfaces> }
, I don’t see why we can’t just generate JS object literal like { optionalArg1: 'value', optionalArg2: true }
Daan
11/14/2020, 2:21 PMDaan
11/14/2020, 2:24 PMSvyatoslav Kuzmich [JB]
11/14/2020, 2:47 PMDaan
11/14/2020, 3:17 PMturansky
11/14/2020, 6:06 PMI don’t see why we can’t just generate JS object literal likeBecause described problem is not about
external interface
, but about missed external options
and have more limitationsturansky
11/14/2020, 6:10 PMread-only
properties
3. Must support optional properties
4. Can have ‘partial’ implementationDaan
11/14/2020, 7:08 PMturansky
11/14/2020, 8:08 PMPoint 2 doesn’t seem like a real requirementIn Kotlin options can be immutable by default (most used case) and have
copy
method
Options used as parameter and parameter mutation - bad practiceturansky
11/14/2020, 8:11 PMturansky
11/14/2020, 8:29 PMDaan
11/15/2020, 10:48 AMSvyatoslav Kuzmich [JB]
11/15/2020, 11:12 AMoption
some kind of new Kotlin concept you proposing? Are they for JS interop only, or intended to be used in general? What advantage would they have over external interfaces?
It’s existed restriction, typical forShould work if we mark property optional. I still don’t see the a problem of implementing it by a class.(edited)options
3. Must support optional propertiesWe can do this currently by abusing interface default implementation. I can see how this can be become nicer with annotation like
@JsOptional
or some modifier.
4. Can have ‘partial’ implementationThe same way Kotlin treats abstract and interface members? Or do you mean something else?
Svyatoslav Kuzmich [JB]
11/15/2020, 11:21 AMfun interface
.
With this feature, usage could look like this:
libraryFunction((optionalArg1: 'value', optionalArg2: true))
turansky
11/15/2020, 2:21 PMAre they for JS interop only, or intended to be used in general?Yes, for JS interop only
I still don’t see the a problem of implementing it by a class.Options has other inheritance rules For example options can be extended “partially” @Svyatoslav Kuzmich [JB] other details I will describe in issue - it will be more productive
Svyatoslav Kuzmich [JB]
11/15/2020, 2:23 PMturansky
11/18/2020, 7:22 PM