How to perform runtime type checking in Dart?
Solution 1
The instanceof-operator is called is
in Dart. The spec isn't exactly friendly to a casual reader, so the best description right now seems to be http://www.dartlang.org/articles/optional-types/.
Here's an example:
class Foo { }
main() {
var foo = new Foo();
if (foo is Foo) {
print("it's a foo!");
}
}
Solution 2
Dart Object
type has a runtimeType
instance member (source is from dart-sdk
v1.14, don't know if it was available earlier)
class Object {
//...
external Type get runtimeType;
}
Usage:
Object o = 'foo';
assert(o.runtimeType == String);
Solution 3
As others have mentioned, Dart's is
operator is the equivalent of Javascript's instanceof
operator. However, I haven't found a direct analogue of the typeof
operator in Dart.
Thankfully the dart:mirrors reflection API has recently been added to the SDK, and is now available for download in the latest Editor+SDK package. Here's a short demo:
import 'dart:mirrors';
getTypeName(dynamic obj) {
return reflect(obj).type.reflectedType.toString();
}
void main() {
var val = "\"Dart is dynamically typed (with optional type annotations.)\"";
if (val is String) {
print("The value is a String, but I needed "
"to check with an explicit condition.");
}
var typeName = getTypeName(val);
print("\nThe mirrored type of the value is $typeName.");
}
Solution 4
There are two operators for type testing: E is T
tests for E an instance of type T while E is! T
tests for E not an instance of type T.
Note that E is Object
is always true, and null is T
is always false unless T===Object
.
Solution 5
Exact type matching is done via runtimeType
property. Checking if an instance or any of its parent types (in the inheritance chain) is of the given type is done via is
operator:
class xxx {}
class yyy extends xxx {}
void main() {
var y = yyy();
print(y is xxx);
print(y.runtimeType == xxx);
}
Returns:
true
false
Related videos on Youtube
![Idolon](https://i.stack.imgur.com/VeomZ.png?s=256&g=1)
Comments
-
Idolon almost 2 years
Dart specification states:
Reified type information reflects the types of objects at runtime and may always be queried by dynamic typechecking constructs (the analogs of instanceOf, casts, typecase etc. in other languages).
Sounds great, but there is no
instanceof
-like operator. So how do we perform runtime type-checking in Dart? Is it possible at all? -
Idolon over 12 yearsLooks like there is no mention of
is
operator at all in the specification. It's better to refere to the grammar file in Dart sources: code.google.com/p/dart/source/browse/trunk/dart/language/… -
Duncan over 12 years@Idolon, the
is
operator is defined on page 59 of the spec, section 10.30 'Type test' -
Günter Zöchbauer over 8 yearsRuntimeType is only for debugging purposes and the application code shouldn't depend on it. It can be overridden by classes to return fake values and probably returns unusable values when transpiled to JS
-
sbedulin over 8 yearsThanks for your remark, I'm pretty new to Dart, and I agree that
runtimeType
may be overriden by classes, although I can't think of a reason why they would. (external code can't set the value sinse it's a getter) Personally, I would stick tois
and reflection. -
Günter Zöchbauer over 8 yearsIt's fine this is mentioned here. It's not very obvious that
runtimeType
has these limitations. -
Matt C about 5 yearsCould you explain what is meant by by
T===Object
? Dart doesn't have the triple equals operator, but you chose to use it rather than double equals, so I assume the difference has significance. -
Matt C about 5 yearsGunter, is it still the case that
runtimeType
should only be used for debugging purposes? I ask because there isn't any mention of this in the docs for Object, or elsewhere (that I could find). -
Duncan about 5 years@MattC That was written more than 7 years ago! I think what I meant was
null is Object
would be true butnull is T
false for any other type T. tbh though I haven't been near Dart for many years now so can't be certain. -
Spyryto about 5 years@MattC yes, I was using
runtimeType
to generate HTML classes on the fly, it works with development build, but fails with release build, e.g. in my case result isminified:ed
instead ofcolumn
-
Lii about 5 years
-
SoftWyer about 5 years
-
Mahdi Imani over 4 yearsit is good solution but, we have error:
Unsupported operation: dart:mirrors is no longer supported for web apps
-
Mahdi Imani over 4 yearsnew syntax is
getTypeName(dynamic obj) => obj.runtimeType;
-
atreeon over 4 years
!=
butis!
...confuses me not it does -
Rob over 4 years@Lii This answer was written for Ecma TC52. See dart.dev/faq
-
vovahost over 4 years@GünterZöchbauer comment is no longer true in Dart 2. It should be fine to use it now.
-
Günter Zöchbauer over 4 years@vovahost I'm mot aware of any related changes. Why do you think my comment is obdolete?
-
vovahost over 4 years@GünterZöchbauer I'm not expert on Dart 2 differences. I commented based on this discussion ibb.co/WcVJzhz ibb.co/zmgq168 Let me know what you think.
-
Günter Zöchbauer over 4 yearsI'm not sure why he thinks it's ok in Dart 2. Perhaps I missed something.
-
TryHard about 4 yearsIs there a way to use the runtimeType to check whether a particular named constructor was used?
-
Yudhishthir Singh about 4 yearsThe Dart Language Tour has sections on equality operators: dart.dev/guides/language/… and type operators: dart.dev/guides/language/language-tour#type-test-operators
-
Ian about 3 yearsBe aware that Flutter, if you're using that, disables reflection (because it breaks tree shaking).
-
Eric Aya almost 3 yearsAs with most programming language, you don't need to add
== true
, the expression itself resolves to a Boolean. You just needif (thing is int)
- and then you see that your solution is actually the same as the accepted answer. -
Muhammad Qasim over 2 yearsHow to use this operator to check Maps because maps can have several types like <Type, type> etc?
-
derekantrican about 2 yearsMake sure you don't combine the two different methods here and end up with
foo.runtimeType is String
that screwed me up for a while.