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.
1 Like
dmt
(Dima Galimzianov)
2
I guess View in your example is SwiftUI.View? It has associatedtype Body which you can use to refer to body's return type.
struct Wot: View {
let model: String?
var body: Optional<some View> {
guard let model else {
return Body.none
}
return Text(model)
}
}
6 Likes
Oh wow, that's so much easier than I feared. Thanks!
(I still think this extra ceremony shouldn't be necessary, but Body.none instead of nil isn't too big a deal)
1 Like
smkuehnhold
(Samuel Kuehnhold)
4
Now that begs the question why
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?
Jumhyn
(Frederick Kellison-Linn)
5
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.)
5 Likes
thai-d-v
(Thai D. V.)
6
What is the purpose of this type? Can you share its View conformance code?
thai-d-v
(Thai D. V.)
8
Sorry, my bad, I didn't know that Optional already conforms to SwiftUI.View, that's why I was asking you to share the protocol conformance code. 
But I am still curious about the purpose of Optional<some View>.
What is the difference between Optional<some View> and _ConditionalContent<Text, EmptyView> when I can define Wot in 2 different ways like these:
struct Wot: View {
let model: String?
var body: Optional<some SwiftUI.View> { // Optional<Text>
guard let model else {
return Body.none
}
return Text(model)
}
}
struct Wot: View {
let model: String?
var body: some View { // _ConditionalContent<Text, EmptyView>
if let model { Text(model) } else { EmptyView() }
}
}
2 Likes
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!).
6 Likes