I want to achieve something like this in swift:
protocol P {}
protocol P1: P {}
class P1Impl: P1 {}
protocol PBase {
associatedtype T: P
var prop: T { get }
}
struct S: PBase {
typealias T = P1 // <---- The problem
// This property is got via DI, so I don't know
// the actual type of it.
@Injected var prop: P1
}
Now the problem is that this code won't compile and the reason is the line typealias T = P1. The compiler wants to know the actual type instead of P1 (while I don't have that type).
I would understand this restriction if the protocol P had a required static property. In that case we can get the value of that property without any instance so the actual type is really needed. However there is no such a property in my case.
Anyway, I like swift and want to solve this task in a swifty way. What is the best practice for this case?
P.S.
I thought generics could help:
struct S<T: P1>: PBase {
var prop: T
}
However in this case also I don't know the type of T when creating an instance of S because of DI which returns a protocol.
In case of any P the code still doesn't compile, I get the same error as before:
protocol PBase {
var prop: P { get }
}
struct S: PBase {
@Injected var prop: P1
}
But there is a workaround, which I think is not the nicest solution.
protocol PBase {
var prop: P { get }
}
struct S: PBase {
@Injected var prop1: P1
var prop: P { prop1 }
}
Also everything gets worse when another protocol which should be inherited from PBase is needed.
As mentioned in one of the comments, I do believe it might be worth checking out the
any Preturn value and whether or not yourassociatedtyperequirement is actually needed. And otherwise you could try to use type erasure:This wraps the P1 implementation into a known type, which will also conform to the
P1protocol. Then in yourSobject, you should do the following:Your
Swill now always know what the type ofTwill be, and the type erasure will contain the actual underlying protocol value.