Search code examples
kotlinkotlin-js-interopkotlin-js

Kotlin: Spread operator on calling JavaScript method


I try to write a type-safe wrapper for a JavaScript library. I need to call a method from JavaScript with variable arguments (e.g. method(args...)). The Kotlin fun for this should work with variable arguments, too. Because Kotlin supports a spread operator, I tried to use it, but Kotlin do not want this.

Example code:

val jsLibrary: dynamic = require("library") // library given by node's require here
fun method(vararg args: String) = jsLibrary.method(*args)

Edit: Forgot to write spread operator '*' in code already. Compiler returns error because of the spread operator.

The Kotlin compiler returns the error "Can't apply spread operator in dynamic call".

Any ideas how to implement a wrapper like this, or do I need any workaround?

Thanks for your help!


Solution

  • Use external fun with @JsModule annotation

    @JsModule("library")
    external fun method(vararg args: String): LibraryMethodReturnType
    

    This will do require("library") for you under the hood. You'll have proper Kotlin types instead of dynamic right away. You'll have no "wrappers", meaning no extra JavaScript call at runtime.


    There is a hacky solution if for you want to manually use require and dynamic types: use apply method to pass all the arguments as an array.

    val jsLibrary: dynamic = require("library")
    fun method(vararg args: String) = jsLibrary.method.apply(null, args)