libraryDependencies += "io.github.gaeljw" %% "typetrees" % typetreesVersion
<dependency>
<groupId>io.github.gaeljw</groupId>
<artifactId>typetrees_${scala.version}</artifactId>
<version>${typetrees.version}</version>
</dependency>
Two implementations are available:
-
using implicits (
given
s) -
using macro
Implementation | Pros 👍 | Cons 👎 |
---|---|---|
Implicits |
Easier |
Only supports up to 4 generic parameters (i.e. a type |
Macro |
Can handle all cases |
Requires to be used in |
import io.github.gaeljw.typetrees.TypeTree
import io.github.gaeljw.typetrees.TypeTreeTag
import scala.reflect.ClassTag
val tag: TypeTreeTag = summon[TypeTree[T]].tag // (1)
val classTag: ClassTag[_] = tag.self // (2)
val actualClass: Class[_] = classTag.runtimeClass
val typeParameters: List[TypeTreeTag] = tag.args // (3)
-
Get a
TypeTreeTag
for a generic typeT
-
Get a
ClassTag
for this type -
Get a
TypeTreeTag
for each type parameters if any
The main usage is as follows:
def someGenericMethod[T](t: T)(using typeTree: TypeTree[T]): String = {
val tag: TypeTreeTag = typeTree.tag
s"I have been called with a parameter of type $tag"
}
someGenericMethod(Map[String, Int]())
// Gives: I have been called with a parameter of type TypeTreeTag(scala.collection.immutable.Map,List(TypeTreeTag(java.lang.String,List()), TypeTreeTag(Int,List())))
Or with context bounds:
def someGenericMethod[T : TypeTree](t: T): String = {
val tag: TypeTreeTag = summon[TypeTree[T]].tag
s"I have been called with a parameter of type $tag"
}
You can find more examples in our tests.
import io.github.gaeljw.typetrees.TypeTreeTag
import io.github.gaeljw.typetrees.TypeTreeTagMacros.typeTreeTag
import scala.reflect.ClassTag
val tag: TypeTreeTag = typeTreeTag[T] // (1)
val classTag: ClassTag[_] = tag.self // (2)
val actualClass: Class[_] = classTag.runtimeClass
val typeParameters: List[TypeTreeTag] = tag.args // (3)
-
Get a
TypeTreeTag
for a generic typeT
-
Get a
ClassTag
for this type -
Get a
TypeTreeTag
for each type parameters if any
The main usage is as follows, within a generic inline
method:
inline def someGenericMethod[T](t: T): String = {
val tag: TypeTreeTag = typeTreeTag[T]
s"I have been called with a parameter of type $tag"
}
someGenericMethod(Map[String, Int]())
// Gives: I have been called with a parameter of type TypeTreeTag(scala.collection.immutable.Map,List(TypeTreeTag(java.lang.String,List()), TypeTreeTag(Int,List())))
Or:
inline def someGenericMapMethod[T <: Map[_,_]](map: T): String = {
val mapTag: TypeTreeTag = typeTreeTag[T]
val keyTag: TypeTreeTag = mapTag.args(0)
val valueTag: TypeTreeTag = mapTag.args(1)
s"I have been called with a Map where key is of type $keyTag and value is of type $valueTag"
}
It can also be applied to non generic types: in such case it doesn’t need to be part of a inline def
but you probably can just use regular ClassTag
then.
You can find more examples in our tests.