Reputation: 406
I'm looking for a way to compare two types in Dart, and get True
when they are the same.
I have a method:
SomeItemType exampleMethod<SomeItemType>(Map<String, dynamic> value) {
if (SomeItemType.toString() == 'BuiltMap<String, String>') {
return BuiltMap<String, String>.from(value) as SomeItemType;
}
// (...)
}
in which I must check if the type-parameter SomeItemType
is actually equal to the type BuiltMap<String, String>
or not.
The only way I found so far is the above string comparions, which is not too elegant in my opinion.
I have tried to following solutions, but they did not work out for me:
SomeItemType is BuiltMap<String, String>
// returns False
SomeItemType == BuiltMap<String, String>
// error: The operator '<' isn't defined for the type 'Type'.
BuiltMap<String, String> is SomeItemType
// error: The operator '<' isn't defined for the type 'Type'.
Upvotes: 2
Views: 2525
Reputation: 832
I needed to check if a variable pointed to a function. This worked for me variable is function
- the word is
Upvotes: 0
Reputation: 71883
You need to detect whether a type variable holds a type which is "the same" as some known type.
I'd probably not go for equality in that check, I'd just check if the type of the variable is a subtype of the known type.
You can do that like:
class _TypeHelper<T> {}
bool isSubtypeOf<S, T>() => _TypeHelper<S>() is _TypeHelper<T>;
// or just ... => <S>[] is List<T>;
...
if (isSubtypeOf<T, BuiltMap<String, String>>()) { ... }
If you want to check type equality, then you have to decide what type equality means. The simplest is "mutual subtyping", which would mean:
bool isMutualSubtypes<S, T>() => isSubtypeOf<S, T>() && isSubtypeOf<T, S>();
// or => isSubtypeOf<S Function(S), T Function(T)>();
// or => isSubtypeOf<void Function<X extends T>() Function(),
// void Function<X extends S>() Function()>();
This will accept, e.g., isMutualSubtypes<void, dynamic>()
because both types are top types.
Type identity is much harder to check because the language itself doesn't have that notion. If types are mutual subtypes, they are considered equivalent at run-time (we distinguish void
and dynamic
statically, but not at run-time).
You can try something like:
bool isSameType<S, T>() => S == T;
but equality of Type
objects is very underspecified, and not guaranteed to work any better than mutual subtyping.
Definitely don't use string comparison:
// Don't use!
bool isSameType<S, T>() => "$S" == "$T"; // BAD!
because it's possible to have different types with the same name.
Upvotes: 4