driis
driis

Reputation: 164291

Swift - type of expression is ambigious without more context

I am trying to make an extension for Alamofire in Swift, and have this code:

import Foundation
import Alamofire

protocol JsonResponse
{
    init?(json : NSObject)
}

extension Request
{
    func responseObject<T : JsonResponse, Error: ErrorType>(completionHandler : Result<T,Error> -> Void) -> Self
    {
        return responseJSON(completionHandler: {r  in
            let result = r.result
            guard result.isSuccess else {
                completionHandler(.Failure(result.error!))
                return
            }
            let obj : T? = T(json : result.value as! NSObject)
            let success : Result<T,Error> = .Success(obj!)
            completionHandler(success)
        })

    }
}

Which gives me the compiler error:

Error:(21, 36) type of expression is ambiguous without more context

Interestingly, when I comment out this line, it compiles:

// completionHandler(.Failure(result.error!))

How do I give Swift enough type information to make this work ?

Upvotes: 0

Views: 365

Answers (3)

Peter Segerblom
Peter Segerblom

Reputation: 2813

I made it compile with this:

completionHandler(Result<T,Error>.Failure(result.error! as! Error))

One problem is the type inferring and the other is that result.error is a optional NSError. I don't know if NSError can be cast to ErrorType tho..

Upvotes: 1

user3441734
user3441734

Reputation: 17544

extension Request
{
    // this function declares return type Self (aka Request)
    func responseObject<T : JsonResponse, Error: ErrorType>(completionHandler : Result<T,Error> -> Void) -> Self
    {
        // here you return ... I don't know, but the type
        // is return type of the function responseJSON,
        // probably Void too
        return responseJSON(completionHandler: {r  in
            let result = r.result
            guard result.isSuccess else {
                completionHandler(.Failure(result.error!))
                // here you return Void
                return
            }
            let obj : T? = T(json : result.value as! NSObject)
            let success : Result<T,Error> = .Success(obj!)
            completionHandler(success)
        })

    }
}

i guess you need something like

func responseObject<T : JsonResponse, Error: ErrorType>(completionHandler : Result<T,Error> -> Void) -> Void

Upvotes: 0

Joseph Lord
Joseph Lord

Reputation: 6504

The problem is that is doesn't know the type of the Result type (.Failure(result.error!)) is. Being the failure case there is nothing that tells the compiler what T will be.

You can write it out in full Result<T,Error>.Failure(result.error!).

Upvotes: 1

Related Questions