DEV Community

DispatchQ
DispatchQ

Posted on

Infer return type with generic Where clause in protocol and extensions.

Let's look at the code:

extension UIView {
    class func loadFromNib<T: UIView>() -> T {
        guard let nib = Bundle(for: T.self)
            .loadNibNamed(String(describing: T.self), owner: nil, options: nil)?.first as? T else {
            fatalError("Missing nib for class.")
        }
        return nib
    }
}

The code gets the job done, it loads an UIView from xib file and returns the view.

But at the call site, the return type is not inferred, we'll have to specify UIView Type like this

let view: ActionView = ActionView.loadFromNib()

to access the properties of ActionView. While swift can infer the type, I don't want to do this.

Instead the same function could be written as a protocol with Where Clause this enables swift to auto infer type.

protocol NibLoadable where Self: UIView {
    static func loadFromNib() -> Self
}

extension NibLoadable {
    static func loadFromNib() -> Self {
        guard let nib = Bundle(
            for: Self.self).loadNibNamed(
            String(describing: Self.self),
            owner: nil,
            options: nil
        )?.first as? Self else {
            fatalError("Missing nib for class.")
        }
        return nib
    }
}

Just conform to this protocol and you'll get the function with automatic type inferring.

With this implementation, the view type is auto inferred by swift.

let view = ActionView.loadFromNib() // view's type is auto inferred.

Top comments (0)