Assuming you actually call gesture1
& gesture2
like this gesture1(geometry: geometry)
since they're functions.
As an ad-hoc solution, you can use map
to also erase the type of Value
.
MySlider()
.gesture(flag ? AnyGesture(gesture1.map { _ in () }) : AnyGesture(gesture2.map { _ in () }))
Explanation:
Firstly, Gesture
has associatedType Value
which can usually be inferred from the concrete type that conforms to it. For example, LongPressGesture.Value == Bool
.
Now, AnyGesture<Value>
is a generic struct with generic parameter Value
. So AnyGesture
are the same type if-and-only-if Value
are the same, for example
AnyGesture<Bool> == AnyGesture<Bool>
AnyGesture<Bool> != AnyGesture<Int>
Since ternary operator ?:
assumes that they're of the same type the equality of Value
is also required.
The potential source confusion is that AnyGesture
uses Value
(generic parameter) to fulfil Gesture.Value
(associatedType).
AnyGesture.Value
can usually be inferred from context, for example:
AnyGesture(gesture1)
can imply AnyGesture<Gesture1.Value>
where Gesture1
is the type of gesture1
. This is from the init signature
// Initializer of `AnyGesture`
init<T: Gesture>(_ gesture: T)
where Value == T.Value
which enforces AnyGesture.Value == T.Value
.
The problem of using some Gesture
as a return value is that, the compiler can not use the actual type of Value
from gesture1
and gesture2
, much less proof that they're equal.
In this case It's very likely that they're not equal from the sheer structure of the gesture1
and gesture2
function.
So, AnyGesture<Gesture1.Value> != AnyGesture<Gesture2.Value>
even if the compiler can infer Value
.
So now I map the Value
on both of them to Void
so that AnyGesture(gesture1.map { _ in () })
is AnyGesture<Void>
which matches AnyGesture(gesture2.map { _ in () })
.