Avoiding generics boilerplate

Let’s say I have a generic type alias with many parameters:

type G[P1 <: B1, P2 <: B2, ..., Pn <: Bn]

Each of the parameters is invariant, and there is no way for me to define an upper bound on it. Now, if I want to define a simple function that has and input and/or output of type G[...], can I avoid the boilerplate illustrated below with the identity function?

def identity[
  P1 <: B1, P2 <: B2, ..., Pn <: Bn
](g: G[P1, P2, ..., Pn]): G[P1, P2, ..., Pn] = g

If there was a way to obtain the type UG that is the union of G[P1 <: B1, P2 <: B2, ..., Pn <: Bn], for all P1 <: B1, P2 <: B2, … Pn <: Bn, then one could conceivably write something like

def identity[T <: UG](g: T): T = g

, which would be much nicer.

P.S.: For a “real-world example”, see here.