google / json_serializable.dart

Generates utilities to aid in serializing to/from JSON.
https://pub.dev/packages/json_serializable
BSD 3-Clause "New" or "Revised" License
1.54k stars 392 forks source link

Use @JsonConverter for map keys. #1393

Open bramp opened 5 months ago

bramp commented 5 months ago

I have a Map<Id, int> whose key is a custom class. That class is is annotated with @JsonConverter for converting it to a String. When I run json_serializable over my code, I get the error

[project]: [SEVERE] json_serializable on lib/src/cart.dart:
[project]:
[project]: Could not generate `toJson` code for `items` because of type `Id`.
[project]: Map keys must be one of: Object, dynamic, enum, String, BigInt, DateTime, int, Uri.

Now Id is not one of those types, but by default it will serialise to a String. So should this use can be supported? More info/example below:

❯ dart --version
Dart SDK version: 3.2.5 (stable) (Tue Jan 16 15:02:13 2024 +0000) on "macos_arm64"
@JsonSerializable()
final class Cart {
  final Map<Id, int> items;
}

@JsonSerializable()
@IdJsonConverter()
final class Id implements Comparable<Id> {
...
}

final class IdJsonConverter extends JsonConverter<Id, String> {
  const IdJsonConverter();

  @override
  Id fromJson(String json) {
    return Id.fromString(json);
  }

  @override
  String toJson(Id object) {
    return object.toString();
  }
}

Map keys must be one of: