protocol SomeView {
associatedtype ViewModel
}
private function foo<T: SomeView>(view: T) where T.ViewModel == Void {
}
But it's not possible to do:
private function foo<T: SomeView>(view: T, viewModel: T.ViewModel) where T.ViewModel != Void {
}
It seems like it's possible to constraint a type to being another type. Then it should be possible to do the opposite. A type is either a type or not, there's no in-between.
or is there some other way of deciding which method can be called based on a type constraint?
The problem with negative constraints is that they don't allow you to write any useful generic algorithms. They tell you what a type isn't or can't do, and nothing about what it is or can do (which is what you actually need to know).
You can absolutely add constraints on associated types, though - either at the protocol level or at the algorithm level: