Ikhwan
Ikhwan

Reputation: 353

Checking what type is passed into a generic method

How do I check what is the type passed as type parameter for a generic method?

foo<T>() {
   // What type is T?
   // I want to able to do something like,
   // if T is String do something, if T is int do something else.
}

Upvotes: 16

Views: 11105

Answers (3)

Easy way:

bool check1<T>() {
  switch (T) {
    case Map<String, dynamic>: return true;
    case List<String>: return true;
    case String: return true;
    default: return false;
  }
}

bool check2<T>() {
  return [Map<String, dynamic>, List<String>, String].contains(T);
}

<<Tested with Dart 2.17>>

Upvotes: 3

lrn
lrn

Reputation: 71613

It depends on why you want to check the type. If you want to special-case a few built-in types like int and String, you can use T == int or T == String.

For more complex types like List<int>, I'd recommend against using == because it only matches the exact type and might miss subtypes like UnmodifiableList<int> that you want to treat the same way (or risk breaking subtype substitutability). There is no direct way to compare two types for being subtypes, but you can use a helper function like:

/// Checks whether [T1] is a (not necessarily proper) subtype of [T2].
bool isSubtype<T1, T2>() => <T1>[] is List<T2>;

Upvotes: 11

matanlurey
matanlurey

Reputation: 8614

You can use the equality (==) operator in the latest Dart SDK versions:

foo<T>() {
  if (T == String) {

  } else if (T == int) {

  }
}

One thing that's not trivial to do is inspect generic types, however:

foo<T>() {
  // Invalid syntax.
  if (T == List<String>) {}
}

In that case, you'll want more specialized methods:

fooOfT<T>(List<T> list) {
  if (T == String) {

  }
}

Upvotes: 45

Related Questions