Extending your gist slightly below:
protocol Theme {
associatedtype Kind
}
struct Theme1: Theme {
typealias Kind = String
let kind: Kind
}
let theme1 = Theme1(kind: "abc")
struct Theme2: Theme {
typealias Kind = Int
let kind: Kind
}
let theme2 = Theme2(kind: 999)
#if SOME_DEFINE
typealias TheTheme = Theme1
let myTheme = theme1
#else
typealias TheTheme = Theme2
let myTheme = theme2
#end
func current() -> TheTheme {
return myTheme
}
Yeah, so you do definitely need to perform type-erasure here. Your type erasure can be a lot more simple though:
protocol Theme {
associatedtype Kind
var value: Kind { get }
}
struct ThemeS: Theme {
typealias Kind = String
let value: Kind
}
struct ThemeI: Theme {
typealias Kind = Int
let value: Kind
}
class AnyTheme<WrappedKind>: Theme {
typealias Kind = WrappedKind
let value: Kind
init<T: Theme>(_ wrapped: T) where T.Kind == WrappedKind {
self.value = wrapped.value
}
}
let current_theme1 = ThemeS(value: "Hello")
func currentTheme() -> AnyTheme<String> {
return AnyTheme(current_theme1)
}
let t = currentTheme()
print(t)