1

I want to check, if my variable k has a type calles T. My approach was

int k=1;
Type T=int;
if(k is T) print('same type');

But it is not working. It works, if I write

if(k is int)

but I want to change the type in a variable.

Thank you for an answer

Sandmann
  • 49
  • 6
  • 1
    This smells possibly like an X-Y problem. Why do you need to do this? There might be better solutions. – jamesdlin Jul 09 '20 at 17:09

3 Answers3

2

You could store the type in a string, and then use runtimeType and toString() to compare the variable's type with the type stored in the string:

int k = 1;
String type = "int";
if (k.runtimeType.toString() == type){
  print("k is an integer");
}
adamgy
  • 4,543
  • 3
  • 16
  • 31
  • You should not use `runtimeType` as it is for debugging. Check the comment on this answer https://stackoverflow.com/a/35950312/12066144 from [@Günter Zöchbauer](https://stackoverflow.com/users/217408/g%c3%bcnter-z%c3%b6chbauer). The issue is that if k is `MyInt` which extends `int`, it is still an `int` but the `if` will be `false` because the `runtimeType` will be `MyInt` and not `int` – Valentin Vignal Oct 12 '22 at 06:12
2

You can't do type checks using Type objects in Dart.

A Type object is not the type, it's just a token representing the type which can be used with the dart:mirrorsreflection library. It cannot, really, be used for anything else.

If you need to do type checking, you need to store the type as a type variable, which means you need something generic, or store it in plain code as a closure.

The closure approach is simpler, but less readable:

int k = 1;
var typeChecker = (o) => o is int;
if (typeChecker(o)) print("k has the right type");

Using a generic helper class is more general:

class Typer<T> {
  bool isType(Object o) => o is T;
  bool operator >=(Typer other) => other is Typer<T>;
  bool operator <=(Typer other) => other >= this;
}
...

var k = 1;
var type = Typer<int>();
if (type.isType(k)) print("k is integer");

In short, don't use Type for anything except dart:mirrors because it isn't really useful for anything else.

lrn
  • 64,680
  • 7
  • 105
  • 121
0

Some Type in the Dart returns a different kind of Type when using .runtimeType.

For example:

void main() async {
  List value = [];
  print(value.runtimeType); // print -> JSArray<dynamic>
}

I am using:

void main() async {
  List value = [];
  print(isSameType(target: value, reference: <Object>[])); // print -> false
  value = [Object()];
  print(isSameType(target: value, reference: <Object>[])); // print -> false
  value = <Object>[];
  print(isSameType(target: value, reference: <Object>[])); // print -> true
}

bool isSameType({required target, required reference}) =>
    target.runtimeType == reference.runtimeType;

class Object {}

But I saw many comments saying the .runtimeType is for debugging and some comments said it will be not available in the future. So I am using this instead of the code above:

void main() async {
  var value;

  value = [];
  print(value.runtimeType); // print -> JSArray<dynamic>
  print(isSameType<List>(value)); // print -> true

  value = [Test];
  print(value.runtimeType); // print -> JSArray<Type>
  print(isSameType<List<Test>>(value)); // print -> false
  print(isSameType<List>(value)); // print -> true

  value = [Test()];
  print(value.runtimeType); // print -> JSArray<Test>
  print(isSameType<List<Test>>(value)); // print -> true
  print(isSameType<List>(value)); // print -> true

  value = <Test>[];
  print(value.runtimeType); // print -> JSArray<Test>
  print(isSameType<List<Test>>(value)); // print -> true
  print(isSameType<List>(value)); // print -> true
}

bool isSameType<type>(target) => target is type;

class Test {}

Basic example for using:

void main() async {
  MyObject phoneNumber = MyObject<int>();
  phoneNumber = await getDataFromUser();
  if (phoneNumber.isSameType()) await uploadData(phoneNumber);
}

class MyObject<type> {
  MyObject({this.data});
  dynamic data;
  bool isSameType() => data is type;
}

Future<dynamic> getDataFromUser() async {
  return null;
}

Future<bool> uploadData(data) async {
  return false;
}