Ian Warburton
Ian Warburton

Reputation: 15706

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.

Upvotes: 5

Views: 1705

Answers (1)

Rob Napier
Rob Napier

Reputation: 299495

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().

Upvotes: 6

Related Questions