The protocol type A is a distinct type from TestB.AType. They aren't interchangable. While the compiler will implicitly convert from TestB.AType to A for you, it can't do this easily to the return value of a dynamically dispatched method—such as a protocol method, or in your case, a read-only property—since it doesn't know the original type it's converting from. It would have to start generating extra methods/properties that wrap the ones you write which do the conversion, which starts to get a bit too magical.
To get around this, you can make the protocol more generic so that each conforming type can specify its own property type:
protocol B {
typealias AType: A
var aType: AType { get }
}
but this means you can no longer use B as a type and can only use it as a contraint for generics (or rather, you can use it as a type, but you won't be able to access the aType property).
The other option is to provide your own wrapper around your property to make it conform to the protocol:
struct TestB : B {
struct AType : A {
}
var _aType: AType
var aType: A {
return _aType
}
init() {
_aType = AType()
}
}