0

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>
13
  • 1
    Your final goal seems kind of pointless. Is there a final final goal? Are you going to pass in types unknown at compile time into getTypeAsArray? Commented Jan 3, 2020 at 0:47
  • 1
    Okay, I don't think this is possible then. What would the function signature look like? It would accept a Any.Type parameter, right? What type would it return? Commented Jan 3, 2020 at 0:51
  • 1
    Generics are bound at compile-time. If you don't know the type at compile time, generics won't help. Continuing on with my previous argument, the method would need to accept a parameter t of type Any.Type. This is so that at runtime, t could store any meta type object. But what would the method return? It can't return [Any].Type, because metatypes are not covariant. Commented Jan 3, 2020 at 1:00
  • 1
    I see your point. There not way to have it return [T].Type and have T determined dynamically because T must be determined at compile time Commented Jan 3, 2020 at 1:01
  • 1
    I see that you are even struggling with a "compile-time only" version of getTypeAsArray. You probably meant func getTypeAsArray<T>(_ value: T.Type) -> [T].Type { return [T].self }. Commented Jan 3, 2020 at 1:03

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

This works for me because in my project I'm already downcasting before passing it through. Thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.