Repository: google/json_serializable.dart

Issue #885: Inheritable JsonKey with Freezed
Created: 2021-05-05T15:51:17Z
This issue is related to rrousselGit/freezed#423
Is your feature request related to a problem? Please describe.
I'm building an API wrapper, and I'm dealing with two JSON object that have numerous shared keys and only a few specific ones. I have an interface like this to implement this:
abstract class MyBaseType {
  @JsonKey(name: 'property_key')
  final String property;
}
And a couple of freezed classes like this:
@freezed
class MySpecializedType extends MyBaseType with _$MySpecializedType {
  const MySpecializedType._();

  const factory MySpecializedType({
    required String property,
    @JsonKey(name: 'another_propery_key') required String anotherProperty,
  }) = _MySpecializedType
}
Normally, when using json_serializable, the JsonKey annotation in the base class will be used in subclasses. This is not happening when using freezed.
Describe the solution you'd like
I'd like JsonKey annotations used in superclasses to be used in freezed subclasses as well.
Describe alternatives you've considered
The only alternative is writing the same annotation everywhere it's needed.

Duplicate issue #1228: The annotation 'JsonKey' can only be used on fields or getters (latest version)
Created: 2022-10-24T18:02:23Z
When I want to use @jsonkey annotation, it gives this error:
"The annotation 'JsonKey' can only be used on fields or getters."
I also use the "freezed" package. It may handle the JSON section.
My versions are here:
dart --version: Dart SDK version: 2.18.0 (stable) (Fri Aug 26 10:22:54 2022 +0000) on "macos_arm64"
flutter --version: Flutter 3.0.4 • channel stable
my code is also here:
part 'note_dtos.freezed.dart';
part 'note_dtos.g.dart';

@freezed
abstract class NoteDto implements _$NoteDto {
  const factory NoteDto({
    @JsonKey(ignore: true) String? id, //here the error
    required String body,
    required int color,
    required List<TodoItemDto> todos,
    @ServerTimestampConverter() required FieldValue serverTimeStamp,
  }) = _NoteDto;

  const NoteDto._();

  factory NoteDto.fromDomain(Note note) {
    return NoteDto(
      id: note.id.getOrCrash(),
      body: note.body.getOrCrash(),
      color: note.color.getOrCrash().value,
      todos: note.todos
          .getOrCrash()
          .map(
            (todoItem) => TodoItemDto.fromDomain(todoItem),
          )
          .asList(),
      serverTimeStamp: FieldValue.serverTimestamp(),
    );
  }

  Note toDomain() {
    return Note(
      id: UniqueId.fromUniqueString(id),
      body: NoteBody(body),
      color: NoteColor(Color(color)),
      todos: List3(todos.map((dto) => dto.toDomain()).toImmutableList()),
    );
  }

  factory NoteDto.fromJson(Map<String, dynamic> json) =>
      _$NoteDtoFromJson(json);

  factory NoteDto.fromFirestore(DocumentSnapshot doc) {
    return NoteDto.fromJson(doc.data()! as Map<String, dynamic>)
        .copyWith(id: doc.id);
  }
}

class ServerTimestampConverter implements JsonConverter<FieldValue, Object> {
  const ServerTimestampConverter();

  @override
  FieldValue fromJson(Object json) {
    return FieldValue.serverTimestamp();
  }

  @override
  Object toJson(FieldValue fieldValue) => fieldValue;
}

@freezed
abstract class TodoItemDto implements _$TodoItemDto {
  const factory TodoItemDto({
    required String id,
    required String name,
    required bool done,
  }) = _TodoItemDto;

  const TodoItemDto._();

  factory TodoItemDto.fromDomain(TodoItem todoItem) {
    return TodoItemDto(
      id: todoItem.id.getOrCrash(),
      name: todoItem.name.getOrCrash(),
      done: todoItem.done,
    );
  }

  TodoItem toDomain() {
    return TodoItem(
      id: UniqueId.fromUniqueString(id),
      name: TodoName(name),
      done: done,
    );
  }

  factory TodoItemDto.fromJson(Map<String, dynamic> json) =>
      _$TodoItemDtoFromJson(json);
}

Closing comment (2022-10-25T17:24:21Z): Duplicate of #885