Gilgamesh
Gilgamesh

Reputation: 337

Swift Xcode getting <<error type>> from generic type parameter inside closure

Swift's way to create a red button:

let button: UIButton = {
      let button = UIButton()
      button.backgroundColor = .red
      return button
}()

With my extension (kotlin's approach):

let button: UIButton = UIButton().apply(){ this in
    this.backgroundColor = UIColor.red
}

There are two problems with my extension, first one is that Xcode doesn't recognize the closure parameter "this", it shows << error type >>, so I don't have autocomplete (although it's working), and the second one is that I would like to be able to infer the generic type since I'm already instantiating it.

The extension:

extension NSObject {
    func apply<T>(_ closure: (T) -> ()) -> T {
        let this = self as! T
        closure(this)
        return this
    }
}

I hope someone can find a solution for this. Thanks in advance.

Upvotes: 1

Views: 394

Answers (2)

Sweeper
Sweeper

Reputation: 274835

The problem here is that Swift cannot infer the type of T. You did not and cannot tell Swift to use the current type as the type of the closure. Self is only available in the result type of methods in a class.

You can do something like this:

func apply<T>(_ obj: T, closure: (T) -> Void) -> T {
    closure(obj)
    return obj
}
apply(UIButton()) { this in this.backgroundColor = .red }

but I don't think that's what you want. You want the word apply to be in the middle, right?

Unfortunately, I cannot think of how you would achieve that. As an alternative, you can try replacing the word "apply" with an operator. For example, I think --> is quite suitable for this.

infix operator -->

func --> <T>(obj: T, closure: (T) -> Void) -> T {
    closure(obj)
    return obj
}
let button = UIButton() --> { this in this.backgroundColor = .red }

Upvotes: 1

Gleb Koval
Gleb Koval

Reputation: 149

I'm not sure why it's not working for you. If the extension is inside a class put it outside of the class so it's on its own. If that is how it is already try clearing the errors with the command (command + k), this will reload them. If the error remains it's very confusing because it is working fine for me.

Upvotes: 0

Related Questions