The problem is that generics are invariant – consider if your checkItem(item:)
function had said:
func checkItem(item: BaseItem<Any>) {
item.param = "foo"
}
That would be illegal for a BaseItem<Int>
, as you cannot possibly assign a String
instance to an Int?
property – which is why it (an instance of Foo
) cannot be typed as a BaseItem<Any>
.
The solution, as other answers have said, is to use a generic placeholder for the function:
func checkItem<T>(item: BaseItem<T>) -> Bool {
return item.param != nil
}
Now, rather than saying that you're taking a BaseItem<Any>
, that has a param
of type Any?
(can be assigned a value of any type) – you're now saying that you're taking a BaseItem
with any specific placeholder type; which will be satisfied at the call-site of the function.
The function implementation itself therefore cannot make any assumptions about this type, and will disallow the assignment of an arbitrary value to param
. The compiler will only allow an assignment of a value of type T
.