Ваша подпись типа говорит, что вызывающий может передать любой тип как ItemType, но затем вам требуется, чтобы закрытие приняло PageData<String>?
.
fetchPage
на самом деле не является универсальным c (он не может принимать типы, выбранные вызывающей стороной), поэтому вы не можете утверждать, что это так. То, что вы имеете в виду, это удалить <ItemType>
и сказать то, что вам нужно:
func fetchPage(page: Int, completion: @escaping (PageData<String>?) -> Void) {
^^ ^^^^^^
Это, однако, нарушает ваш протокол PagedServiceProvider, потому что этот протокол требует, чтобы TestPagedServiceProvider принимал абсолютно любой ItemType, а это не , Вам нужно решить, что вы на самом деле имеете в виду. Здесь вы можете иметь в виду протокол со связанным типом, который представляет собой тип, который реализация выбирает вместо вызывающего.
protocol PagedServiceProvider: class {
associatedtype ItemType
func fetchPage(page: Int, completion: @escaping (PageData<ItemType>?) -> Void)
}
Однако это создает некоторые головные боли, поскольку теперь PagedServiceProvider не может быть легко помещен в массиве (это уже не конкретный тип). То, как вы справляетесь с этим, во многом зависит от того, какую проблему вы на самом деле решаете. Не существует общего решения, которое всегда уместно.