Getting a more specific generic type than dynamic

Viewed 51

Consider the following minimal example:

class Clazz<T> {}

Clazz<R> join<R, A extends R, B extends R>(Clazz<A> a, Clazz<B> b) => Clazz<R>();

void main() {
  final a = Clazz<int>();
  final b = Clazz<double>();

  print(a);  // 'Clazz<int>'
  print(b);  // 'Clazz<double>'
  print(join(a, b));  // 'Clazz<dynamic>', but would like 'Clazz<num>'
}

I would expect that calling join would return an instance of Clazz with the most specific generic type, yet Dart always infers dynamic as the generic type. I also tried without success with a static extension method (same problem) and with a method within the class itself (unable to specify type constraints). What can I do to get the desired behavior?

1 Answers

In join<R, A extends R, B extends R>, A extends R and B extends R set constraints on what A and B can be. The compiler will not compute the most specific common base type of A and B to infer R; it just needs to find any type R that satisfies the constraint.

Clazz<int> is a Clazz<num> (and likewise for Clazz<double>), so you can do what you want by simplifying join to remove the A and B types:

Clazz<R> join<R>(Clazz<R> a, Clazz<R> b) => Clazz<R>();

and now whe you call join(a, b), the compiler will automatically find the most specific common base type of Clazz<int> and Class<double> to satisfy a common Clazz<R>.

Related