Search code examples
swiftfunctiongenericsprotocols

Swift protocol conformance when returning a generic


Here's an example:

protocol Feed {
    func items<T>() -> [T]? where T: FeedItem
}

protocol FeedItem {}

class FeedModel: Feed, Decodable {
    func items<T>() -> [T]? where T : FeedItem {
        return [FeedItemModel]() // Error: Cannot convert return expression of type '[FeedItemModel]' to return type '[T]?'
    }
}

class FeedItemModel: FeedItem, Decodable {}

Why does it:

A) try to convert to T when T is a generic, not a type? B) does not recognize FeedItemModel as conforming to FeedItem?


Solution

  • A)

    T is a type, a homogenous concrete type specified at runtime.
    Imaging T is class Foo : FeedItem it's obvious that FeedItemModel cannot be converted to Foo

    B)

    FeedItemModel is recognized as conforming to FeedItem but this is irrelevant.


    It's often a mix-up of generics and protocols. Generic types are not covariant. If you need covariant types use an associated type.