Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert from one promise type to another

If I have one function which returns a promise and calls another function which also returns a promise, is it possible to convert between the two without doing this...

func f1() -> Promise<Any?> { ... }

func f2() -> Promise<Void> {

   return f1().then { value -> Void in

      ...
   }
}

If I don't have the .then call, the compiler cannot convert from one type to another.

like image 403
Ian Warburton Avatar asked Dec 01 '16 14:12

Ian Warburton


1 Answers

No. First, generics aren't covariant in Swift. You can't pass a [String] where you expect an [Any], so you can't convert from Promise<Void> to Promise<Any?>. In your case it's even worse, since you're trying to convert from Promise<Any?> to Promise<Void>, and a Any? is not a Void.

You may be thinking of Void as somehow special, like it means "nothing" in a magical, compiler way. That's not what Void is. It's just a typealias for the empty tuple (()). You can't convert from Any? to (). Imagine if you could do that. Then I could write this:

var list: [Void] = [] // This is just as legal as Promise<Void>
f2().then { x: Void in
    list.append(x)
}

Now I've appended some random Optional onto my array of (). That's going to crash and the compiler won't save me.

You could of course create a helper to do this if you wanted, like:

extension Promise {
    func ignoringResult() -> Promise<Void> {
        return self.then { _ in }
    }
}

And then you could write:

func f2() -> Promise<Void> {
    return f1().ignoringResult()
}

PromiseKit already has this converter: Promise.asVoid().

like image 57
Rob Napier Avatar answered Sep 19 '22 04:09

Rob Napier