The issue is: you want to leverage type checking to statically verify the sanity of a state machine, correct?
TL;DR: In currently released Swift 5.8, no.
I don't think this is possible. In order to leverage the type checking, you would need to work with concrete types at all times (in the checked scope). This rules out using some/any, because they hide the type information at "code writing time."
Anyway. You have a States and Events and there is a subset of State ✕ Event ✕ State where 1st state is the current state, event is the event and 2nd state is the resulting state. In this case, the 2nd state is the function of 1st state and event.
The really naive solution would be to use plain old function overloading. Consider having
struct StateA {
func handle(_ event: Event1) -> StateB { StateB() }
func handle(_ event: Event2) -> StateC { StateC() }
}
struct StateB {
}
struct StateC {
}
struct Event1 {}
struct Event2 {}
Now, where to go from here? We would like to abstract upon this code to create a protocol, but as suggested by:
currently in such protocol, we can declare only "1:1" type associations, where in your case, we would need to be able to do set operation with types which is not possible.
And now for something completely different
You might want to look at upcoming Swift Macros and parameter packs. You might define something like:
where PossibleOutcomes would be "tuple of tuples" like ((Event1, StateB), (Event2, StateC)) and the handle function would be forbidden to call directly.
In this case I could imagine a macro, that would look at your PossibleOutcomes tuple of tuples and generate those overloaded functions for you.
Also, Macros can emit their own diagnostic messages to the user (since they are essentially compiler plugins) and you could somehow use them to implement the type checking you're looking for. But I think this would be a considerable effort to do correctly.
However, even if this would work, Macros are still work-in-progress feature and I would not advice sinking too much time into it before it is released.