Closures, in theory, support this, but they don't support argument labels. 
You can annotate them, but you can't use those at call site (anymore).
struct Type {
typealias Method = (
_ parameter0: Bool,
_ parameter1: Int
) -> String
init(method: Method? = nil) {
self.method = method
}
private let method: Method?
}
If the method doesn't throw, this solution is pretty decent, to get the labels back:
struct MethodNotAssignedError: Error { }
extension Type {
func method(
argument0 parameter0: Bool,
argument1 parameter1: Int
) throws -> String {
guard let method = method
else { throw MethodNotAssignedError() }
return method(parameter0, parameter1)
}
}
try Type().method(argument0: false, argument1: 1) // MethodNotAssignedError()
try Type { _, _ in "🧵" } .method(argument0: false, argument1: 1) // 🧵
If it does, you have to figure out why, via catch. Or, you can optionally return a curried closure.
extension Type {
func getMethod(
argument0 parameter0: Bool,
argument1 parameter1: Int
) -> ( () throws -> String )? {
method.map { method in
{ try method(parameter0, parameter1) }
}
}
}
try Type().getMethod(argument0: false, argument1: 1)?() // nil
try Type { _, _ in "🧵" } .getMethod(argument0: false, argument1: 1)?() // 🧵