Store Swift closures and cast them back to their original type

I'm trying to create a class that can save different closures (or methods) with an argument of a specific subtype of Decodable that should be called later. This way I can predefine what actions, or methods, can be called on that class in response to some input. For example, the line addCallback(setOption(_:), SetOptionRequest.self) should result in the subsequent call to try! performCallback("setOption", JSONEncoder().encode(SetOptionRequest()) to call setOption(data) where the argument data has type SetOptionRequest.

Here is the code I have so far (I took the bit about DecodableWrapper from here). The problem is that at runtime the cast callback.callback as! (ActionRequest) throws -> Void fails, since the type of the closure is not (ActionRequest) throws -> Void but (SetOptionRequest) throws -> Void. But I have no idea if and how I can cast the closure back to its original type. I considered using Selectors but I would like to keep the compile-time check that I'm binding methods with their correct argument type.

struct DecodableWrapper: Decodable {
    static var baseType: ActionRequest.Type!
    var base: ActionRequest

    init(from decoder: Decoder) throws {
        self.base = try DecodableWrapper.baseType.init(from: decoder)
    }
}

open class Server {

    private var actionCallbacks = [String: (callback: Any, dataType: ActionRequest.Type)]()

    open func setup() {
        addCallback(setOption, action: SetOptionRequestResponse.self)
    }

    public func addCallback<T: ActionRequest>(_ callback: @escaping (_ data: T) throws -> Void, action: T.Type) {
        actionCallbacks[T.action] = (callback, T.self)
    }

    private func performCallback(action: String, data: Data) throws {
        let callback = actionCallbacks[action]!
        DecodableWrapper.baseType = callback.dataType
        let data = try! JSONDecoder().decode(DecodableWrapper.self, from: data).base
        try (callback.callback as! (ActionRequest) throws -> Void)(data)
    }

    private func setOption(_ data: SetOptionRequest) {
    }

}

protocol ActionRequest {
    static var action: String
}

struct Request: SetOptionRequest {
}

Could you show how you tried to use selector ?

Well, I quickly discarded that idea since as far as I know there's no way of checking at compile-time that a selector has a specific signature.

Store Swift closures and cast them back to their original type
 
 
Q