How to perform runtime type checking in Dart?

162,964

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
Share:
162,964

Related videos on Youtube

Idolon
Author by

Idolon

Volo @ Mercedes-Benz.io

Updated on July 17, 2022

Comments

  • Idolon
    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
    Idolon over 12 years
    Looks 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
    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
    Günter Zöchbauer over 8 years
    RuntimeType 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
    sbedulin over 8 years
    Thanks 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 to is and reflection.
  • Günter Zöchbauer
    Günter Zöchbauer over 8 years
    It's fine this is mentioned here. It's not very obvious that runtimeType has these limitations.
  • Matt C
    Matt C about 5 years
    Could 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
    Matt C about 5 years
    Gunter, 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
    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 but null 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
    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 is minified:ed instead of column
  • Lii
    Lii about 5 years
  • SoftWyer
    SoftWyer about 5 years
    is and is! can be found in the Operators section of the Dart language tour.
  • Mahdi Imani
    Mahdi Imani over 4 years
    it is good solution but, we have error: Unsupported operation: dart:mirrors is no longer supported for web apps
  • Mahdi Imani
    Mahdi Imani over 4 years
    new syntax is getTypeName(dynamic obj) => obj.runtimeType;
  • atreeon
    atreeon over 4 years
    != but is!...confuses me not it does
  • Rob
    Rob over 4 years
    @Lii This answer was written for Ecma TC52. See dart.dev/faq
  • vovahost
    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
    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
    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
    Günter Zöchbauer over 4 years
    I'm not sure why he thinks it's ok in Dart 2. Perhaps I missed something.
  • TryHard
    TryHard about 4 years
    Is there a way to use the runtimeType to check whether a particular named constructor was used?
  • Yudhishthir Singh
    Yudhishthir Singh about 4 years
    The 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
    Ian about 3 years
    Be aware that Flutter, if you're using that, disables reflection (because it breaks tree shaking).
  • Eric Aya
    Eric Aya almost 3 years
    As with most programming language, you don't need to add == true, the expression itself resolves to a Boolean. You just need if (thing is int) - and then you see that your solution is actually the same as the accepted answer.
  • Muhammad Qasim
    Muhammad Qasim over 2 years
    How to use this operator to check Maps because maps can have several types like <Type, type> etc?
  • derekantrican
    derekantrican about 2 years
    Make 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.