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?
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!");
}
}
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);
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.
runtimeType
has these limitations.
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.");
}
Unsupported operation: dart:mirrors is no longer supported for web apps
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
.
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.
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.
var isAuthFailure = Failure is! AuthenticationFailure;
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
Just to clarify a bit the difference between is
and runtimeType
. As someone said already (and this was tested with Dart V2+) the following code:
class Foo {
@override
Type get runtimeType => String;
}
main() {
var foo = Foo();
if (foo is Foo) {
print("it's a foo!");
}
print("type is ${foo.runtimeType}");
}
will output:
it's a foo!
type is String
Which is wrong. Now, I can't see the reason why one should do such a thing...
Simply use .runtimeType
on the property like below,
print(unknownDataTypeProperty.runtimeType)
T
is The type
print( T.runtimeType)
https://i.stack.imgur.com/aFx70.png
https://i.stack.imgur.com/rQRGh.png
print("enter your phone number:\n"); var phone number = stdin.readLineSync();
if(phone number.runtimeType is int == true) // checks if the values input are integers
{
print('you have successfully input your phone number!');
}
else{
print('only numbers are allowed');
}
== 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.
Success story sharing
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/…is
operator is defined on page 59 of the spec, section 10.30 'Type test'is
andis!
can be found in the Operators section of the Dart language tour.getTypeName(dynamic obj) => obj.runtimeType;
!=
butis!
...confuses me not it does