I would like to perform runtime subtype checking in Dart without using dart:mirrors.
What I mean by this is that given two types A and B, either as variables with type Type or as type arguments on a generic class (i.e the variables being checked would be, using List as a dummy class, List<A> and List<B>), I would like to check if A is a subtype of B.
Here is some code written with dart:mirrors that performs what I want:
bool isSubtype(Type a, Type b) => reflectType(a).isSubtypeOf(reflectType(b));
// OR
bool isSubType<A, B>(List<A> a, List<B> b) => reflect(a).type.typeArguments[0].isSubtypeOf(reflect(b).type.typeArguments[0]);
I would like to perform this check without using dart:mirrors. I have tried using the following code:
bool isSubType<A, B>(List<A> a, List<B> b) => <A>[] is List<B>;
However, while this code works with expressions with a static type:
print(isSubType(<Iterable>[], <Iterable>[])); // true
print(isSubType(<Iterable>[], <List>[])); // true
print(isSubType(<Iterable>[], <String>[])); // false
it does not work with expressions without a static type:
List a = <Iterable>[];
List<List> types = [<Iterable>[], <List>[], <String>[]];
for (final type in types) {
print(isSubType(type, a)); // true, true, true
}
How can I implement isSubType to get the correct result for types that are unknown at compile-time?
Note: I don't need this to be compatible with the JS runtime, just AOT and JIT compiled Dart.
If all you want is to chcek the subtype relation of two types, you don't need arguments at all, only type arguments.
You also can't extract the runtime type of an object as a type argument. I'm guessing that's what you are trying to do with the arguments and type inference, but type inference happens at compile-time and only uses the static types of the arguments. The call
print(isSubType(type, a))infers the typeList<dynamic>for both type arguments from the expressionstypeanda, and does so at compile-time and independently of the actual run-time type that variable will contain.There is no general way, outside of
dart:mirrors, to check whether two objects have runtime types that are related to each other, because it's not possible to get the runtime type of an object into a type variable.You also can't do anything similar with
Typeobjects. ATypeobject is only really good for passing intodart:mirrors, and maybe compare for equality. It doesn't understand subtyping at all.