title: How to properly type a javascript callback function in scala-js when creating a facade
body: <p>For many javascript libraries with async operations you pass a callback function. I've read this <a href="https://stackoverflow.com/questions/28581329/interop-between-js-and-scala-functions-in-scala-js">SO question</a>, <a href="https://stackoverflow.com/questions/28558820/typed-fa%C3%A7ade-for-js-library-in-scala-js">this one too</a>, and <a href="http://www.scala-js.org/doc/calling-javascript.html" rel="nofollow noreferrer">read the docs</a> but am still a bit confused as to how to properly type a callback function in scala-js when creating a facade.  I am writing a facade for <a href="http://cloudinary.com/documentation/upload_widget" rel="nofollow noreferrer">Cloudinary's upload widget</a> and it has an openUploadWidget method that takes options and a callback like the following example from their docs:</p>
  
  <pre class="lang-js prettyprint-override"><code>cloudinary.openUploadWidget(
    { cloud_name: 'demo', upload_preset: 'a5vxnzbp'}, 
    function(error, result) { console.log(error, result) });
  </code></pre>
  
  <p>This is what I implemented so far in my scala-js facade:</p>
  
  <pre class="lang-scala prettyprint-override"><code>object Cloudinary {
    def openUploadWidget(
        options: WidgetOptions,
        callback: (Either[String, Seq[UploadResult]]) =&gt; Unit): Unit = {
      _Cloudinary.openUploadWidget(
          options, 
          (error: String, results: js.Array[js.Dynamic]) =&gt; {
              callback(Option(results)
                  .filterNot(_.isEmpty)
                  .map(_.toSeq.map(_.asInstanceOf[UploadResult]))
                  .toRight(error))
          })
    }    
  }    
  
  @JSName("cloudinary")
  object _Cloudinary extends js.Object {
    def openUploadWidget(
        options: WidgetOptions,
        callback: js.Function2[String, js.Array[js.Dynamic], _]): Unit = js.native
  }
  
  trait WidgetOptions extends js.Object {
    @JSName("cloud_name") val cloudName: String = js.native
    @JSName("upload_preset") val uploadPreset: String = js.native
  }
  
  object WidgetOptions {
    def apply(cloudName: String, uploadPreset: String): WidgetOptions = {
      js.Dynamic.literal(
        cloud_name = cloudName, 
        upload_preset = uploadPreset).asInstanceOf[WidgetOptions]
  }
  
  trait UploadResult extends js.Object {
    @JSName("public_id") val publicId: String = js.native
    @JSName("secure_url") val secureUrl: String = js.native
  }
  </code></pre>
  
  <p>And you would use it like:</p>
  
  <pre class="lang-scala prettyprint-override"><code>def callback(results: Either[String, Seq[UploadResult]]): Unit = {}
  
  def show(): Unit = {
    Cloudinary.openUploadWidget(
        WidgetOptions(
            cloudName = "demo",
            uploadPreset = "a5vxnzbp"),
        callback _)
  }
  </code></pre>
  
  <p>I implemented a small wrapper to translate from the javascript callback args into something more Scala-ish because I couldn't figure out how to type the callback in a more direct fashion.  This isn't bad, IMHO, but I have a sneaking suspicion that I'm not understanding something and it could be done a lot better.</p>
  
  <p>Any help/suggestions?</p>