IMO, there is nothing wrong with downcasting here. To make it clear that downcasting is intentional, I would wrap it into a computed property:
public protocol ServerResponse
{
}
public protocol CacheableResponse: ServerResponse
{
var cacheKey:MD5 { get }
}
extension ServerResponse {
var asCachable: CacheableResponse? { self as? CacheableResponse }
}
And if you want to avoid lookup in the conformance tables, you could make this property part of protocol requirements:
public protocol ServerResponse
{
var asCachable: CacheableResponse? { get }
}
public protocol CacheableResponse: ServerResponse
{
var cacheKey:MD5 { get }
}
extension ServerResponse {
var asCachable: CacheableResponse? { nil }
extension CacheableResponse {
var asCachable: CacheableResponse? { self }
}