swiftprotocolscovariant-return-types

Is there a way to set a typealias of a protocol's associated type in a sub protocol?


I didn't see this in the similar questions, so I think this is unique. I have a protocol

protocol Zot {}

protocol Foo {
    associatedType Bar: Zot
    var prop1: Bar { get set }
}

Now I could say

class Zoty: Zot {}

class Fooy: Foo {
    typealias Bar = Zoty
    var prop1: Zoty = Zoty()
}

But I haven't quite moved to the class layer yet. Is there a way for me to set the type alias in a protocol like so?

protocol Fooie: Foo {
    typealias Bar = Zoty
    var prop1: Zoty { get set }
}

The compiler says to make it like this

protocol Fooie: Foo where Bar == Zoty {
    var prop1: Bar { get set }
}

But then it throws the error Cannot override mutable property 'prop1' of type 'Self.Bar' with covariant type 'Zoty'


Solution

  • To fix the error, just remove this line in Fooie

    var prop1: Bar { get set }
    

    You do not need to redeclare this again, and I do agree the error message is a bit confusing. Swift thinks that you are trying to override the property, which as far as it is concerned, is declared to be a different type, but in this context, the two types can only be the same.

    After removing the property, you can now do:

    class Fooy: Fooie {
        var prop1 = Zoty()
    }
    

    and this gives errors

    class SomethingElse: Zot {}
    
    class Fooy: Fooie {
        var prop1 = SomethingElse()
    }
    

    'Fooie' requires the types 'SomethingElse' and 'Zoty' be equivalent

    Type 'Fooy' does not conform to protocol 'Fooie'