Reputation: 24
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.
Upvotes: 0
Views: 345
Reputation: 71603
If all you want is to chcek the subtype relation of two types, you don't need arguments at all, only type arguments.
bool isSubtype<S, T>() => <S>[] is List<T>;
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 type List<dynamic>
for both type arguments from the expressions type
and a
, 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 Type
objects. A Type
object is only really good for passing into dart:mirrors
, and maybe compare for equality. It doesn't understand subtyping at all.
Upvotes: 3