Search code examples
swiftgenericsprotocolsxcode10

Could not infer generic parameter when calling protocol static method


Using a Playground and given these definitions:

import Foundation

protocol MoneyTrakObject {
    var key: String { get set }

    init()
}

extension MoneyTrakObject {
    static func objectFromDB<T: MoneyTrakObject>(for key: String, queue: DispatchQueue? = nil, completion: @escaping (T) -> Void) -> String? {
            // after data is retrieved, call completion closure
            let valueObject = T()
            completion(valueObject)

        return "dbToken"
    }
}


protocol Transaction: MoneyTrakObject {
    var amount: Int { get set }
}


struct BasicTransaction: Transaction {
    var key = UUID().uuidString
    var amount = 0

    init() {}
}

struct RecurringTransaction: Transaction {
    var key = UUID().uuidString
    var amount = 0

    init() {}
}

I would expect that I could do this:

let token1 = BasicTransaction.objectFromDB(for: "") { (transaction) in
    // use transaction
}

let token2 = RecurringTransaction.objectFromDB(for: "") { (transaction) in
    // use transaction
}

However I get the Generic parameter 'T' could not be inferred error when calling the static method and I'm not sure why.


Solution

  • I do not see why you need the generic constraint. If you change the extension of your protocol to this:

    extension MoneyTrakObject {
        static func objectFromDB(for key: String, queue: DispatchQueue? = nil, completion: @escaping (Self) -> Void) -> String? {
            // after data is retrieved, call completion closure
            let valueObject = Self()
            completion(valueObject)
    
            return "dbToken"
        }
    }
    

    Your code compiles just fine. Self is a placeholder for the actually implementing type.