runtimeCast function Null safety

dynamic runtimeCast(
  1. dynamic object,
  2. TypeMirror intoType
)

Implementation

dynamic runtimeCast(dynamic object, TypeMirror intoType) {
  final exceptionToThrow =
      TypeCoercionException(intoType.reflectedType, object.runtimeType);

  try {
    final objectType = reflect(object).type;
    if (objectType.isAssignableTo(intoType)) {
      return object;
    }

    if (intoType.isSubtypeOf(reflectType(List))) {
      if (object is! List) {
        throw exceptionToThrow;
      }

      final elementType = intoType.typeArguments.first;
      final elements = object.map((e) => runtimeCast(e, elementType));
      return (intoType as ClassMirror).newInstance(#from, [elements]).reflectee;
    } else if (intoType.isSubtypeOf(reflectType(Map, [String, dynamic]))) {
      if (object is! Map<String, dynamic>) {
        throw exceptionToThrow;
      }

      final output = (intoType as ClassMirror)
          .newInstance(Symbol.empty, []).reflectee as Map<String, dynamic>;
      final valueType = intoType.typeArguments.last;
      object.forEach((key, val) {
        output[key] = runtimeCast(val, valueType);
      });
      return output;
    }
  } on TypeError catch (_) {
    throw exceptionToThrow;
  } on TypeCoercionException catch (_) {
    throw exceptionToThrow;
  }

  throw exceptionToThrow;
}