struct Wot: View {
let model: String?
var body: Optional<some View> {
guard let model else {
return nil
}
return Text(model)
}
}
Underlying type for opaque result type 'Optional' could not be inferred from return expression
Using .none instead of nil simply changes it to:
Type of expression is ambiguous without a type annotation
The code as written seems like it should work, in principle. While I understand literally what the compiler errors say, I don't understand why it thinks it needs me to spell the type information out for it. It's clear what the opaque return type is from the non-nil return.
Is this something that may be fixed in future?
Is there a workaround, in the interim?
[Assume that it's impossible to specify the opaque type even if I wanted to, because in the real world cases where I'm hitting this, that type isn't available to me as it's pre-opaqued by SwiftUI view modifiers, or is a horrendously complicated type that's practically impossible to deduce¹.]
¹ Tangentially, I so very much wish Swift had a ? (or whatever) type placeholder like some languages, whereby the compiler / IDE just figures it out for me and amends the code.
struct Wot: View {
let model: String?
var body: Optional<some View> {
guard let model else {
return Body.none
}
return Text(model)
}
}
can't be replaced with
struct Wot: View {
let model: String?
// error: 'some' types are only permitted in properties, subscripts, and functions
typealias Body = (some View)?
var body: Body {
guard let model else {
return Body.none
}
return Text(model)
}
}
because TIL opaque types can be used to satisfy associatedtype requirements, but only implicitly?
Opaque types are not proper types in-and-of themselves. They must, at the point of declaration, have some underlying type that the compiler is able to determine. When detached from a declaration which can provide that type, as in typealias Body = (some View)?, the compiler (today) has no way to determine what the underlying type should be. (We don't attempt to 'link' the opaque type to body across the typealias.)
I wrote a little about that as part of Hiding SwiftUI views. Result builders have a lot of limitations (and some annoyances), so it's often nice to disable them. That you can do this with SwiftUI is often overlooked (I myself didn't consciously realise I was in fact doing this until just recently!).