Q:

Get the specific simple name of a generic type in Scala

Is it possible to get the type name of a generic class in Scala? I know this isn't possible in Java with type erasure, but I was hoping that Scala would be a different case.
Currently I have to do something similar to this:
trait Model
case class User(id: String) extends Model

def fromMap[M<:Model : Manifest](data: Map[String, String], modelType: String) = {
  modelType match {
    case "user" => User(data.get("id").get)
  }
}

val user = fromMap[User](Map("id" -> "id1"), "user")

Obviously it would be easier if I could work out "user" without having to have it passed in.

A:

Class name can be retrieved from a Manifest (or a ClassManifest) with manifest.erasure.getName (erasure is the Class instance). For instance
def className[A : ClassManifest] = classManifest[A].erasure.getName

Edit : Seen Derek's answer, which makes this stuff with erasure.getName look rather stupid. I didn't consider toString. Still I hope what follows may be of interest
The difference between using ClassManifest and Manifest is that in the Manifest for a generic class, the type parameter are guaranteed to be available, while they are best effort in ClassManifest (compare signatures of typeParameters in both classes). The drawback of this guarantee is that a Manifest might not be implicitly available where a ClassManifest would be.
Have you considered using typeclasses instead?
trait BuilderFromMap[A] {def build(data: Map[String, String]): A} 
  // or better, return Option[A], accounting for possible failure
object User {
   implicit val Builder extends BuilderFromMap[User] {...}
}
def fromMap[A](data: Map[String, String])(implicit builder: BuilderFromMap[A])
  = builder.build(data)

This way, calls to fromMap will compile only if a Builder is available for this particular class, rather than fail with a MatchError. 

A:

For those of you coming to this question from a world with Scala 2.12.x or 2.13.x, ClassTag[T] is the preferred way to do this.
import scala.reflect._ 

trait Model 
case class User(id: String) extends Model 

def fromMap[M <: Model : ClassTag](data: Map[String, String]) = {
  val modelType = implicitly[ClassTag[M]].runtimeClass.getSimpleName
  modelType match {
    case "User" => User(data("id"))
  }
} 

val user = fromMap[User](Map("id" -> "id1"))

