joehinkle11
joehinkle11

Reputation: 512

Swift type-variable to generic-type-variable

The error I get is unsurprising, but how would I accomplish something like this in Swift?

let stringType = String.self
let stringArrayType = Array<String>.self
let stringArrayTypeFromVariable = Array<stringType>.self // Error :Use of undeclared type 'stringType'

My final goal is to build a function like this.

print( getTypeAsArray( Int.self ) ) // prints "Array<Int>.Type"
print( getTypeAsArray( String.self ) ) // prints "Array<String>.Type"

Here's my current attempt. It doesn't compile, but I think maybe this is solvable with generics like this.

// this version doesn't compile...
func getTypeAsArray<T>(_ value: T) -> [T].Type {
    return []
}
getTypeAsArray(String.self)

// this version compiles, but doesn't give me the functionality I want...The expected output was Array<String>, not Array<String.Type>
func getTypeAsArray<T>(_ value: T) -> [T].Type {
    return type(of: [])
}
getTypeAsArray(String.self) // -> Array<String.Type>

Upvotes: 0

Views: 869

Answers (1)

Sweeper
Sweeper

Reputation: 271070

You can achieve your final goal by doing something like this:

func getTypeAsArray<T>(_ value: T.Type) -> [T].Type { 
    return [T].self 
}

But this won't work in situations like this:

let t: UIView.Type = UITableView.self
print(getTypeAsArray(t))

You'd expect it to print Array<UITableView>, but it prints Array<UIView>.

Unfortunately, I don't think the you can make the above case work as well. Because such a method must accept an Any.Type, but what would its return type be? It can't return a [Any].Type because although metatypes are covariant, metatype arrays are not:

let t: [UIView].Type = [UITableView].self

error: cannot convert value of type [UIView].Type to specified type [UITableView].Type

Upvotes: 1

Related Questions