Home > database >  Is there a generic Type in Dart like Class<T> in Java/Kotlin?
Is there a generic Type in Dart like Class<T> in Java/Kotlin?

Time:05-17

In Kotlin I can do something like:

var myType : KClass<String>? = null

and can assign to it like:

myType = String::class

but NOT like:

myType = Int::class // Type mismatch: inferred type in KClass<Int> but KClass<String>? was expected

Is there something similar in Dart? I know of the Type type but it is not generic and while it can represent String or List<int> I seem not to be able to write similar code as my Kotlin example:

Type? t = null;

I can assign to it:

t = String;

AND also:

t = int;

but I want the second example to fail compilation. I would need some kind of Type<String>. Is this possible in Dart?

CodePudding user response:

The Type class is not generic, and doesn't support subtype checks (or any other reasonable type-related operation). There is no way to use it for what you are trying to do.

So, don't. It's useless anyway. However, in Dart you can create your own type representation that is actually useful, because Dart doesn't erase type arguments, and you can then ask people using your code to ass that instead.

Say:

class MyType<T> implements Comparable<MyType>{ // Or a better name.
  const MyType();
  Type get type => T;
  bool operator >=(MyType other) => other is MyType<T>;
  bool operator <=(MyType other) => other >= this;
  bool isInstance(Object? object) => object is T;
  R runWith<R>(R Function<T>() action) => action<T>();
  @override
  int get hashCode => T.hashCode;
  @override
  bool operator==(Object other) => other is MyType && T == other.type;
}

With that you can write:

MyType<String?> type;
type = MyType<Null>(); // valid
type = MyType<String>(); // valid
type = MyType<Never>(); // valid
type = MyType<int>; // EEEK! compile-time error

You can use it where you need to store a type as a value.

The thing is, most of the time you can just use a type variable instead ,and creating an actual value to represent a type is overkill. So, first try to just use a type parameter, instead of passing around Type or MyType objects. Only if that fails should you consider using MyType. Using Type is probably a mistake since it's not good for anything except doing == checks, which is antithetical to object orientation's idea of subtype subsumption.

CodePudding user response:

I think this is the best you can get :

void main() {
  aFunction<String>(String, '');
  aFunction<String>(String, 1);
}

void aFunction<V>(Type type, V value) {
  print(value.toString());
}

if you run this in a dartpad, you will see that

aFunction<String>(type, 1);

Doesn't compile.

But that's not really efficient because the type isn't guessed by Dart, you have to specify the generic type by hand.

I'm using Dart 2.17

  • Related