Search code examples
genericstypesswiftintrospection

Get the name (string) of a generic type in Swift


I have a generic class of type T and I would like to get the name of the type that passed into the class when instantiated. Here is an example.

class MyClass<T> {
    func genericName() -> String {
        // Return the name of T.
    }
}

I have been looking around for hours and I can't seem to find any way to do this. Has anyone tried this yet?

Any help is greatly appreciated.

Thanks


Solution

  • A pure swift way to achieve that is not possible.

    A possible workaround is:

    class MyClass<T: AnyObject> {
        func genericName() -> String {
            let fullName: String = NSStringFromClass(T.self)
            let range = fullName.rangeOfString(".", options: .BackwardsSearch)
            if let range = range {
                return fullName.substringFromIndex(range.endIndex)
            } else {
                return fullName
            }
        }
    }
    

    The limitations relies on the fact that it works with classes only.

    If this is the generic type:

    class TestClass {}
    

    NSStringFromClass() returns the full name (including namespace):

    // Prints something like "__lldb_expr_186.TestClass" in playground
    NSStringFromClass(TestClass.self)
    

    That's why the func searches for the last occurrence of the . character.

    Tested as follows:

    var x = MyClass<TestClass>()
    x.genericName() // Prints "TestClass"
    

    UPDATE Swift 3.0

    func genericName() -> String {
        let fullName: String = NSStringFromClass(T.self)
        let range = fullName.range(of: ".")
        if let range = range {
            return fullName.substring(from: range.upperBound)
        }
        return fullName
    }