I have a case where I am trying to define a function that takes in an array of objects with the requirement that each object must define a string-based enum called 'Commands'.
Here's an example of how you would do it if you were using an associated type:
protocol CommandSetProtocol {
associatedtype Command : RawRepresentable where Command.RawValue == String
var commands:[Command] { get }
}
class FooCommands : CommandSetProtocol {
enum Command : String {
case commandA = "Command A"
case commandB = "Command B"
}
let commands = [
Command.commandA,
Command.commandB
]
}
class LaaCommands : CommandSetProtocol {
enum Command : String {
case commandC = "Command C"
case commandD = "Command D"
}
let commands = [
Command.commandC,
Command.commandD
]
}
The problem is you can't do this because of that associated type:
var commandSets:[CommandSetProtocol.Type] = [
FooCommands.self,
LaaCommands.self
]
Of note: I'm trying to stop someone form doing this, which should fail compilation because the Raw type is not a string.
class BadCommands : CommandSetProtocol {
enum Command : Int {
case commandE = 1
case commandF = 2
}
let commands = [
Command.commandE,
Command.commandF
]
}
How can this (or similar) be achieved?

Eliminating all the red herrings in the question, you are really just pointing out the well-known fact that this sort of thing is legal:
... but this sort of thing is not:
The problem is that you hit the "can only be used as a generic constraint" wall. That wall is due to be torn down in a future version of Swift, but until then, the way to make that array is to use type erasure.