gaeljw / typetrees

This library is intended to solve the use case of getting the erased types of a (generic) parameter. Something which was possible in Scala 2 with TypeTag and is now a bit more complex with Scala 3.

Version Matrix

TypeTrees

Table of Contents
typetrees 3.0.0 M3
badge

This library is intended to solve the use case of getting the erased types of a (generic) parameter. Something which was possible in Scala 2 with TypeTag and is now a bit more complex with Scala 3.

This is implemented thanks to a macro.

Warning: for most use cases, it needs to be part of a inline method.

Get it

sbt
libraryDependencies += "io.github.gaeljw" % "typetrees" % typetreesVersion
Maven
<dependency>
  <groupId>io.github.gaeljw</groupId>
  <artifactId>typetrees_${scala.version}</artifactId>
  <version>${typetrees.version}</version>
</dependency>

Usage

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)
  1. Get a TypeTreeTag for a generic type T

  2. Get a ClassTag for this type

  3. Get a TypeTreeTag for each type parameters if any

Examples

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"
}

Or:

inline def someGenericMapMethod[K,V](map: Map[K,V]): String = {
    val keyTag: TypeTreeTag = typeTreeTag[K]
    val valueTag: TypeTreeTag = typeTreeTag[V]
    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.