letOrNull<T> function

T? letOrNull<T>(
  1. dynamic input
)

Attempts to convert a dynamic input to the specified type T, returning Null on failure.

This is a high-level dispatcher that uses more specific let...OrNull helpers based on the target type T.

Supported types:

Implementation

T? letOrNull<T>(dynamic input) {
  assert(
    !(isSubtype<T, List<dynamic>>() && !isSubtype<List<dynamic>, T>()) &&
        !(isSubtype<T, Set<dynamic>>() && !isSubtype<Set<dynamic>, T>()) &&
        !(isSubtype<T, Iterable<dynamic>>() &&
            !isSubtype<Iterable<dynamic>, T>()) &&
        !(isSubtype<T, Map<dynamic, dynamic>>() &&
            !isSubtype<Map<dynamic, dynamic>, T>()),
    'letOrNull<$T> cannot be used with specific collection types due to type safety. '
    'Only generic collection types are supported.',
  );
  if (input is T) return input;
  if (input == null) return null;
  final raw = () {
    if (typeEquality<T, double>() || typeEquality<T, double?>()) {
      return letDoubleOrNull(input);
    } else if (typeEquality<T, int>() || typeEquality<T, int?>()) {
      return letIntOrNull(input);
    } else if (typeEquality<T, bool>() || typeEquality<T, bool?>()) {
      return letBoolOrNull(input);
    } else if (typeEquality<T, DateTime>() || typeEquality<T, DateTime?>()) {
      return letDateTimeOrNull(input);
    } else if (typeEquality<T, Uri>() || typeEquality<T, Uri?>()) {
      return letUriOrNull(input);
    } else if (isSubtype<T, List<dynamic>>()) {
      return letListOrNull<dynamic>(input);
    } else if (isSubtype<T, Set<dynamic>>()) {
      return letSetOrNull<dynamic>(input);
    } else if (isSubtype<T, Iterable<dynamic>>()) {
      return letIterableOrNull<dynamic>(input);
    } else if (isSubtype<T, Map<dynamic, dynamic>>()) {
      return letMapOrNull<dynamic, dynamic>(input);
    } else if (typeEquality<T, String>() || typeEquality<T, String?>()) {
      return letAsStringOrNull(input);
    }
    return input;
  }();

  return letAsOrNull<T>(raw);
}