Skip to content

Map<String, [...]> is incorrectly typed as <String?, [...]> #1188

@eximius313

Description

@eximius313

flutter --version
is:

Flutter 3.0.1 • channel stable • https://github.com/flutter/flutter.git
Framework • revision fb57da5f94 (3 months ago) • 2022-05-19 15:50:29 -0700
Engine • revision caaafc5604
Tools • Dart 2.17.1 • DevTools 2.12.2

Having such code:

import 'package:json_annotation/json_annotation.dart';

part 'json_serialize_bug.g.dart';

void main() {
  var testSerialize = TestSerialize(myEnum: MyEnum.one, myMap: {MyEnum.two: 2});
  TestSerialize.fromJson(testSerialize.toJson());
}

@JsonSerializable()
class TestSerialize {
  final MyEnum myEnum;
  final Map<MyEnum, int> myMap;
  TestSerialize({
    required this.myEnum,
    required this.myMap,
  });

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

  Map<String, dynamic> toJson() => _$TestSerializeToJson(this);
}

enum MyEnum {
  one, two
}

fails with:

Unhandled exception:
type '_InternalLinkedHashMap<String?, int>' is not a subtype of type 'Map<String, dynamic>' in type cast
#0      _$TestSerializeFromJson (package:test/json_serialize_bug.g.dart:12:29)
#1      new TestSerialize.fromJson (package:test/json_serialize_bug.dart:19:64)
#2      main (package:test/json_serialize_bug.dart:7:17)
#3      _delayEntrypointInvocation.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:297:19)
#4      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:192:12)

Because _$TestSerializeToJson:

Map<String, dynamic> _$TestSerializeToJson(TestSerialize instance) =>
    <String, dynamic>{
      'myEnum': _$MyEnumEnumMap[instance.myEnum],
      'myMap': instance.myMap.map((k, e) => MapEntry(_$MyEnumEnumMap[k], e)),
    };

uses MapEntry which is being resolved to _InternalLinkedHashMap<String?, int> instead of _InternalLinkedHashMap<String, int> and I think, that adding type:

'myMap': instance.myMap.map((k, e) => MapEntry<String, dynamic>(_$MyEnumEnumMap[k]!, e)),

would work, because we can never have null here.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions