Search code examples
swiftgenericsdata-structuresxcode11

Swift Generic parameter 'T' could not be inferred


I have a generic dictionary, and built a generic function to access that dictionary (to prevent concurrency access problems).

My (singleton) data class looks like:

class AppData {
    static let genericDict: Dictionary<String, Any> = [:]
    
    static func genericGet<T: Any>(_ objID: String) -> T {
        let retVal: T
        mySemaphore.wait()
        retVal = genericDict[objID] as! T
        mySemaphore.signal()
        return retVal
    }
}

However, when I call my function like so:

class SomeClass {
     let product: SomeObj = AppData.genericGet(objID) as! SomeObj
}

I get the error: Generic parameter 'T' could not be inferred

I both explicitly and implicitly cast the type to my desired value. Not sure what else I can do to fix this issue.

I've tried restarting XCode, does not help.

The real code:

public class AppData: ObservableObject {
    static private var dataDirectory: Dictionary<String, Any> = Dictionary(minimumCapacity: 10000)
    
    static let dataGetLock = DispatchSemaphore(value: 1)
    static func get<T: Any>(_ objID: String) -> T? {
        let retVal: T
        dataGetLock.wait()
        retVal = dataDirectory[objID] as! T
        dataGetLock.signal()
        return retVal
    }
}

I get the error on the following two lines:

class StoreViewEnvironment: ObservableObject {
    func initProductLoad(storeID: String) {
    ...
        let liveStore: Store = AppData.get(storeID) as! Store
        let liveMenu: Menu = AppData.get(liveStore.menuID) as! Menu
    ... 
   }
}

Solution

  • I don't approve of the way you're doing this (on the general grounds that Any is just about always a bad smell), but here's a version that compiles (just delete the Any constraint):

    class AppData {
        static let genericDict: Dictionary<String, Any> = [:]
        
        static func get<T>(_ objID: String) -> T {
            let retVal: T
            retVal = genericDict[objID] as! T
            return retVal
        }
    }
    
    class SomeClass {
        let product : String = AppData.get("yoho")
    }