# Generic Function: member does not exist

**URL:** <https://forums.swift.org/t/generic-function-member-does-not-exist/29790>\
**Category:** Using Swift\
**Created:** [October 13, 2019, 5:27pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790 "2019-10-13T17:27:39Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![powing](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@powing](https://forums.swift.org/u/powing)\
**Post date:** [October 13, 2019, 5:27pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/1 "2019-10-13T17:27:39Z")

</div>

I have a number of buttons of which inherit from a single parent class and calculate their image based on a single generic function. I would like to use a value that I know exists on the class(es) but get the error that the member doesn't exist.

```swift
func determineImage<T>(with item: HelperStrings, forComponent: T?) -> String {
    
    var returnImagery: String = ""
    
    switch item {
    case .firstButton :
        returnImagery = UIDevice.current.userInterfaceIdiom == .pad ? forComponent?.but3PadSm.rawValue ?? "but1PadSm" : forComponent?.but3PhoneSm.rawValue ?? "but1PhoneSm"
    case .secondButton :
        returnImagery = UIDevice.current.userInterfaceIdiom == .pad ? forComponent?.but3PadSm.rawValue ?? "but2PadSm" : forComponent?.but3PhoneSm.rawValue ?? "but2PhoneSm"
    case .thirdButton :
        returnImagery = UIDevice.current.userInterfaceIdiom == .pad ? forComponent?.but3PadSm.rawValue ?? "but3PadSm" : forComponent?.but3PhoneSm.rawValue ?? "but3PhoneSm"
    }
    return returnImagery
}

```

---

<div class="post-metadata">

**Author:** ![DeFrenZ](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/defrenz/32/827_2.png) [@DeFrenZ](https://forums.swift.org/u/DeFrenZ)\
**Post date:** [October 13, 2019, 5:33pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/2 "2019-10-13T17:33:21Z")

</div>

The way you wrote the code, the generic type is unconstrained. i.e. simply `T`.  
So the code — as the compiler interprets it — will have to work with _any_ type, not just your buttons' type.

If you want to make use of specific properties of the generic component, you can add constraints to it in a `where` clause before the body of the function, e.g.

```swift
func determineImage<T>(with item: HelperStrings, forComponent: T?) -> String where T: MyButtonParentClass {
  /* your code here */
}

```

---

<div class="post-metadata">

**Author:** ![powing](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@powing](https://forums.swift.org/u/powing)\
**Post date:** [October 13, 2019, 9:43pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/3 "2019-10-13T21:43:06Z")

</div>

Many thanks DeFrenZ, such a simple solution.

I would now like to import an array of buttons in one compatible type, specify the output type and then export them in an array, but I am having issues with initialization:

```swift
func convertToButton<T, V>(from items: [T], withClass: V) -> [V] where T: Class1, T: Class2 {
        
    var returnButtonArray: [V] = []
    
        for item in items {
            
            let itemButton: V = {
                
                let buttonData = V(imageNamed: "", title: "", buttonAction: {

                    switch buttonLogic {
                    case 1 : print("button1")
                    case 2 : print("button2")
                    case 3 : print("button3")
                    }
                })
                
                buttonData.title = item.title
                buttonData.zPosition = 1
                
                return buttonData
            }()

            returnButtonArray.append(itemButton)
        }
    return returnButtonArray
}

```

I was underuse if I would have to list the possible types in the where clause, which doesn't make much sense, but found it got rid of some of the errors.

---

<div class="post-metadata">

**Author:** ![sveinhal](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/sveinhal/32/3992_2.png) [@sveinhal](https://forums.swift.org/u/sveinhal)\
**Post date:** [October 14, 2019, 8:18am UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/4 "2019-10-14T08:18:10Z")

</div>

If you want to pass V, the type, and not an instance of V, you need to use `V.Type` in the function signature.

Also, whenever you find yourself creating a mutable result array, and then iterating over another array, performing some transformation on it, and appending to your result, you're basically creating a one-to-one mapping between some input collection and an output. You could then use `.map` for clarity, brevity and avoiding mutable state:

```swift
func convertToButton<T, V>(from items: [T], withClass: V.Type) -> [V] where T: Class1, T: Class2 {
    return items.map { item in 
        let button = V.init(imageNamed: "", title: item.title, buttonAction: { /* ... */ })
        button.zPosition = 1
        return button
    }
}

```

---

<div class="post-metadata">

**Author:** ![powing](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@powing](https://forums.swift.org/u/powing)\
**Post date:** [October 14, 2019, 5:18pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/5 "2019-10-14T17:18:40Z")

</div>

That's a sensible use of map for my needs, I never thought of that, thank you.

Playing with the code I cannot get past the error that there Type 'V' has no member 'init', unless using T, but that to me seems backwards as I am obtaining my data from that, not initializing from it.

I tried adding a required init to my class (which has no custom initializers) but it did no good. My understanding of how this generic function works is that items are imported as T, which conform to either of the where classes, and I convert T to V with by initializing with the values, outputting in the specified V class.

Why will only T allow for the init and not V?

---

<div class="post-metadata">

**Author:** ![powing](https://avatars.discourse-cdn.com/v4/letter/p/8edcca/32.png) [@powing](https://forums.swift.org/u/powing)\
**Post date:** [October 27, 2019, 7:08pm UTC](https://forums.swift.org/t/generic-function-member-does-not-exist/29790/6 "2019-10-27T19:08:35Z")

</div>

I understand now what I was getting wrong.

In the end I used a parent class that had all of the members I would need to switch on in the generic function, so that I could use it in the generic function.

Thanks !
