Home > other >  Swift Generics Generic parameter could not be inferred
Swift Generics Generic parameter could not be inferred

Time:01-28

I'm trying to create a protocol that has a function with generic parameters.

protocol APIRequest {
    static func fetchData<T: Codable>(completion: @escaping(T?, NetworkError?) -> Void)
}

then I have a struct that conforms the protocol

static func fetchData<Ztar: Codable>(completion: @escaping (Ztar?, NetworkError?) -> Void) {
        let url = URLConstructor.url(scheme: "https", host: "swapi.dev" , path: "/api")
        guard let url = url else { return }
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            guard let data = data else {
                completion(nil, NetworkError.badResponse)
                return
            }
            do {
                let decoder = JSONDecoder()
                let object = try decoder.decode(Ztar.self, from: data)
                completion(object, nil)
            } catch {
                print(error)
            }
        }
        task.resume()
    }

but I'm not sure if that implementation of the type of the generic is correct because in my ViewController I'm receiving the error Generic parameter 'Ztar' could not be inferred

NetworkManager.fetchData { star, error in
            
}

Can someone explain What I'm doing wrong?

CodePudding user response:

It's not possible to implement this correctly. What type is Ztar? How would the compiler know? You've written "fetchData will fetch some kind of data, out of all the infinitely possible kinds of data in the universe, and you, the compiler, should decode it." That's not possible.

Instead, the way this would generally be written is:

fetchData<T: Codable>(ofType: T.Type, completion: @escaping (Result<T, NetworkError>) -> Void)

And then you would need to pass the type you expect as the first parameter:

fetchData(ofType: Record.self) { resultRecord in ... }

If you don't know what type Ztar is, how can the compiler?

(Note that you should almost never use (T?, Error?) as a type. That says "maybe T, maybe Error, maybe neither, maybe both." You almost always mean Result<T, Error> instead. That says "either T or Error.")

  •  Tags:  
  • Related