Anders Cheow
Anders Cheow

Reputation: 127

Expression type '()' is ambiguous without more context when using generic closure

I'm having this error when trying to create my own generic closure.

I can't find any potential solution for this problem.

Full code:

func customRequest<T : Codable>(_ target: Api, whenSuccess: @escaping CustomCompletion<T>, whenError: @escaping (String) -> Void) {
        super.request(target, callbackQueue: .none, progress: .none, completion: { result in
            switch result {
            case let .success(response):
                if let data = try? JSONDecoder().decode(BaseAPIModel<T>.self, from: response.data) {
                    if data.isValid(), let result = data.result {
                        whenSuccess(result)
                    } else {
                        whenError(data.toErrorReadableString())
                    }
                } else {
                    whenError("Something had gone wrong. Please try again.")
                }
            case let .failure(error):
                if let response = error.response, let data = try? JSONDecoder().decode(BasicAPIModel.self, from: response.data) {
                    whenError(data.toErrorReadableString())
                } else {
                    whenError("Something had gone wrong. Please try again.")
                }
            }
        })
    }

fileprivate func getLogo() {
        // Error come from this line
        ApiProvider().customRequest(Api.prefetchLogo, whenSuccess: { _ in

        }, whenError: { (error) in

        })
    }

Upvotes: 0

Views: 610

Answers (1)

Rob Napier
Rob Napier

Reputation: 299475

The compiler has no way to determine what type T is for CustomCompletion<T> this code. There are two ways to provide it.

Add it to the passed parameters of customRequest, for example as a fetching parameter:

func customRequest<T : Codable>(_ target: Api, fetching: T.Type, 
                                whenSuccess: @escaping CustomCompletion<T>, 
                                whenError: @escaping (String) -> Void) {

Then it would be called as:

ApiProvider().customRequest(Api.prefetchLogo, fetching: Something.self, ...

Or add a type to the closure parameter:

ApiProvider().customRequest(Api.prefetchLogo, whenSuccess: { (_: Something) in

While you don't care what the returned value is, the compiler still has to generate code to decode it, and it needs to know its type somehow.

Upvotes: 1

Related Questions