Search code examples
javascalagenericsreflectionscala-reflect

How to get field names and field types from a Generic Type in Scala?


In Scala, given a generic type T, how to retrieve the list of field names and the field types? For example, if I have the case class:

case class Person(name: String, age: Int, gender: Boolean)

And the generic function:

def getFieldNamesAndTypes[T](): Seq[(String, String)]

I would like to be able to retrieve a sequence (in order that the fields appear) of the fields (name, type):

val fieldNamesAndTypes = getFieldNamesAndTypes[Person]()

Solution

  • It seems that you need the reflection API:

    Welcome to Scala 2.13.1 (OpenJDK 64-Bit Server VM, Java 1.8.0_222).
    Type in expressions for evaluation. Or try :help.
    
    scala> import scala.reflect.runtime.universe._
    import scala.reflect.runtime.universe._
    
    scala> def getFields[T: TypeTag] = typeOf[T].members.collect {
         |   case m: MethodSymbol if m.isCaseAccessor => (m.name.toString, m.returnType.toString)
         | }
    getFields: [T](implicit evidence$1: reflect.runtime.universe.TypeTag[T])Iterable[(String, String)]
    
    scala> case class Person(name: String, age: Int, gender: Boolean)
    defined class Person
    
    scala> getFields[Person]
    res0: Iterable[(String, String)] = List((gender,Boolean), (age,Int), (name,String))