skip to Main Content

I am in the middle of writing a library to dynamically serialise/deserialise any object in Dart/Flutter (Similar in idea to Pydantic for Python). However, I am finding it impossible to implement the last component, dynamic type casting. This is required in order convert types from JSON, such as List to List (or similar). The types are retrieved from objects using reflection.

The below is the desired implementation (though as far as I understand this is not possible in Dart).

Map<String, Type> dynamicTypes = {"key": int };

// Regular casting would be "1" as int
int value = "1" as dynamicTypes["key"];

Is there some workaround which makes this possible to implement? Or have I reached a dead end with this (hence no other dynamic serialisation/deserialisation package already exists).

2

Answers


  1. Chosen as BEST ANSWER

    Conducting more research into this issue, it seems in Dart's current implementation this is impossible due to runtime reflection being disabled as referenced here in the official docs.

    There are ongoing discussions about the support for this and the associated package dart:mirrors here on GitHub, but so far though there is some desire for such functionality it is highly unlikely to ever be implemented.

    As a result, the only options are:

    • Use code generation libraries to generate methods.
    • Manual serialisation/deserialisation methods.
    • Implement classes with complex types such as lists and maps to be dynamic, enabling (all be it limited) automatic serialisation/deserialisation.

  2. Your question does not specify how exactly dynamicTypes is built, or how its key is derived. So there is perhaps a detail to this that is not clear to me.

    But what about something like this?

    class Caster<T> {
      final T Function(String) fromString;
      Caster(this.fromString);
    }
    
    void main() {
      Map<String, Caster> dynamicTypes = { "key": Caster<int>((s) => int.parse(s)) };
      int v = dynamicTypes['key']!.fromString('1');
      print(v);
    }
    

    Or, if you have the value as a dynamic rather than a string:

    class Caster<T> {
      T cast(dynamic value) => value as T;
    }
    
    void main() {
      Map<String, Caster> dynamicTypes = { "key": Caster<int>() };
      dynamic a = 1;
      int v = dynamicTypes['key']!.cast(a);
      print(v);
    }
    

    Or even more succinctly:

    void main() {
      dynamic a = 1;
      int v = a;
      print(v);
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search