как определить фасад для метода, который генерирует события в ScalaJS

Я пишу фасад scalajs для pouchdb.

код: https://gist.github.com/chandu0101/62013de47bf5ee4d2412

как определить фасад для имени API changes, который генерирует события и возвращает метод отмены..


person invariant    schedule 16.02.2015    source источник


Ответы (1)


Определение типов фасадов Scala.js — это предоставление статических типов JavaScript API. Обычно в документации JavaScript упоминаются типы, поэтому их можно довольно легко преобразовать в формальное определение.

В этом случае методы changes возвращают EventEmitter, что вам нужно в первую очередь. . Определим этот тип и, в частности, его метод on:

class EventEmitter extends js.Object {
  def on(event: String, listener: js.Function): this.type = js.native
  ...
}

К сожалению, мы должны быть очень неточными для типа listener, потому что фактический тип будет очень сильно зависеть от строки события и конкретного использования этого эмиттера. В общем, на данный момент мы ничего не можем предсказать.

В документации EventEmitter не упоминается метод cancel(), что немного странно, поскольку очевидно, что этот метод может быть вызван для эмиттера, возвращаемого changes. Итак, мы определим подтип для конкретного эмиттера, возвращаемого changes:

trait ChangesEventEmitter extends EventEmitter {
  def cancel(): Unit = js.native
}

Мы также можем воспользоваться этим специализированным свойством, чтобы включить более точный тип слушателя для определенных событий. В этом случае сделаем это для события change:

object ChangesEventEmitter {
  implicit class ChangesEventEmitterEvents(
      val self: ChangesEventEmitter) extends AnyVal {
    def onChange(listener: js.Function1[js.Dynamic, Any]): self.type =
      self.on("change", listener)
  }
}

Наконец, вам нужен тип для параметра options метода db.changes. Сам тип обычно является трейтом со многими неизменяемыми полями:

trait DBChangesOptions extends js.Object {
  val include_docs: js.UndefOr[Boolean] = js.native
  val limit: js.UndefOr[Int] = js.native
  ...
}

Чтобы создать экземпляр такого типа, вы можете использовать метод apply в сопутствующем объекте с аргументами по умолчанию (см. это ТАК вопрос), или вы можете создать для него класс, подобный Builder.

И теперь мы можем, наконец, объявить сам метод changes:

def changes(options: DBChangesOptions = ???): ChangesEventEmitter = js.native
person sjrd    schedule 16.02.2015
comment
большое спасибо, что касается параметров и объектов-компаньонов, я уже делаю это для других методов, которые вы можете проверить по существу :) - person invariant; 16.02.2015
comment
не могли бы вы объяснить мне, как работает объект-компаньон ChangesEventEmitter...? - person invariant; 23.02.2015
comment
Он работает так же, как и любой другой неявный класс. Там нет ничего специфичного для Scala.js. - person sjrd; 23.02.2015