Prohibit generic type at compile-time

I have the following implicit classes defined

object Implicits
  implicit class JsonObject[T](val t: T) extends AnyVal {
    def as[U](implicit writes: Writes[T], reads: Reads[U]): U = toJson(t).as[U]
  }

  implicit class JsonString(val str: String) extends AnyVal {
    def as[T](implicit reads: Reads[T]): T = parse(str).as[T]
  }
}

I’d like to prohibit users from using JsonObject[String] because JsonString is more efficient. I’ve noticed that when I import Implicits.* the compiler correctly picks JsonString over JsonObject for “”.as[Foo], but if a user accidentally imports Implicits.JsonObject, I’d like it to be a compiler error. I can add a require(!t.isInstanceOf[String]), but there is a runtime performance hit for doing so. Is there a way to do it at compile time with no overhead?

You may use or re-implement Shapeless =:!=


BTW, you want to make those vals private[Implicits] otherwise you are adding a identity extensions t and str :slight_smile:

2 Likes