Open
Description
Today runtimeType
is (mis?)used for the following scenarios:
See usage in Flutter for some background.
Also see issues with .runtimeType
in Dart2JS: #31329
Ease of use in implementing operator==
class A {
@override
bool operator ==(dynamic other) {
if (other.runtimeType != this.runtimeType) {
return false;
}
final A typedOther = other;
// .. do checks ..
}
}
Examples
Checking that the type of an object is exactly something:
abstract class A {}
class _ConcreteA implements A {}
void useA(A a) {
if (a.runtimeType != _ConcreteA) {
throw 'Do not subclass "A"';
}
}
Examples:
Note that is check would not be necessary with #27372.
Outputting debug information about a class instance:
abstract class A {
var field1;
var field2;
@override
String toString() => '$runtimeType: {$field1, $field2}';
}
Examples
I believe most of these cases could be addressed without more expensive reified types by introducing a .classType
or Type.classOf
. In JavaScript this could simply map to the already present prototype:
class Type {
// Pardon my weak dart2js-foo.
@patch static Type classOf(dynamic instance) => wrapJsType(JS('#.constructor', instance));
}
One of the cases it doesn't address is generic types, for example:
class A<T> {}
void main() {
var a = new A<String>();
print(Type.classOf(a)); // 'A' not 'A<String>'
}
... but that might be reasonable, and allow better optimizations in most scenarios.