Let's say I have a protocol "ValueProvider", which is just something that provides a value:protocol ValueProvider
{
typealias ValueType
func valueInContext(context: ValueProviderContext) -> ValueType
}I have various structs that implement this protocol, such as:struct Constant<T>: ValueProvider
{
var value: T
init(value: T)
{
self.value = value
}
func value(context: ValueProviderContext) -> T
{
return value
}
}and many other such (generic) structs.I have another struct, Thing, that has properties which are value provides of particular type. Ideally, I would like to express it like this:struct Thing
{
var position: ValueProvider<CGPoint>
var name: ValueProvider<String>
...
}Unfortunately I cannot do this, because ValueProvider is a protocol (which cannot be generic in current version of Swift), and ValueProvider<String> is illegal as a property type.It looks to me I basically have two options:(1) Make a new generic ThingProperty<T> enum, use that as the type of the "position" and "name" properties. The enum will have a value provider as its associated value. I don't like this solution because it forces me to change my model only because the type system cannot express what I want, although the runtime shouldn't have any problem with what I want. It feels like changing my model just to make the typechecker happy, which is absurd.(2) Instead of "ValueProvider<CGPoint>", I can just use "ValueProvider" as the type of the position (and name) properties. This works and allows me to keep the model simple, but I loose the benefits of static typing to a large degree - the system doesn't know that the "position" and "model" properties can only hold CGPoint and String value providers, respectively. As a consequence, when I call valueInContext method on those properties, type checker wouldn't know the correct type of the return value.What's the "correct" approach to take here? Am I missing something?