Skip to content

Commit 0f383e7

Browse files
authored
Serializing enums explicitly references types unless nullable (issue … (#1146)
Before this change, serializing non-nullable enums in a subtype was incorrectly producing nullable string types. For example, serializing a class member of type Map<enum, String> produced a type Map<String?, dynamic> where Map<String, dynamic> should have been produced. Nullable enums should still produce nullable types, eg. serializing List<enum?> should produce List<String?> fixes #1145
1 parent 4982848 commit 0f383e7

16 files changed

+175
-83
lines changed

_test_yaml/test/src/build_config.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
of type `MyClass?`. ([#822](https://github.com/google/json_serializable.dart/issues/822))
55
- Added support for `JsonSerializable(converters: <JsonConverter>[])`
66
([#1072](https://github.com/google/json_serializable.dart/issues/1072))
7+
- Fix issue with serialization of non-nullable enumerations emitting a nullable
8+
type ([#1146](https://github.com/google/json_serializable.dart/pull/1146))
79

810
## 6.2.0
911

json_serializable/lib/src/type_helpers/enum_helper.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,11 @@ class EnumHelper extends TypeHelper<TypeHelperContextWithConfig> {
2929

3030
context.addMember(memberContent);
3131

32-
return '${constMapName(targetType)}[$expression]';
32+
if (targetType.isNullableType) {
33+
return '${constMapName(targetType)}[$expression]';
34+
} else {
35+
return '${constMapName(targetType)}[$expression]!';
36+
}
3337
}
3438

3539
@override

json_serializable/test/default_value/default_value.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/test/default_value/default_value.g_any_map__checked.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/test/default_value/implicit_default_value.g.dart

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/test/integration/integration_test.dart

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,23 @@ void main() {
304304
expect(dayTypeEnumValues, ['no-good', 'rotten', 'very-bad']);
305305
});
306306

307+
test(
308+
'serializing a non-nullable enum as a key in a map should produce a '
309+
'non-nullable string key', () {
310+
final cls =
311+
Issue1145RegressionA(status: {Issue1145RegressionEnum.gamma: true});
312+
// Due to issue 1145 this resulted in Map<String?, dynamic>
313+
expect(cls.toJson()['status'], const TypeMatcher<Map<String, dynamic>>());
314+
});
315+
316+
test(
317+
'serializing a nullable enum in a list should produce a list with'
318+
' nullable entries', () {
319+
final cls = Issue1145RegressionB(status: [Issue1145RegressionEnum.gamma]);
320+
// Issue 1145 should not have affected nullable enums
321+
expect(cls.toJson()['status'], const TypeMatcher<List<String?>>());
322+
});
323+
307324
test('unknown as null for enum', () {
308325
expect(
309326
() => Issue559Regression.fromJson({}).status,

json_serializable/test/integration/json_enum_example.dart

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,35 @@ enum Issue559RegressionEnum {
4949
beta,
5050
gamma,
5151
}
52+
53+
enum Issue1145RegressionEnum {
54+
alpha,
55+
beta,
56+
gamma,
57+
}
58+
59+
@JsonSerializable(
60+
createFactory: false,
61+
)
62+
class Issue1145RegressionA {
63+
Issue1145RegressionA({
64+
required this.status,
65+
});
66+
67+
Map<String, dynamic> toJson() => _$Issue1145RegressionAToJson(this);
68+
69+
final Map<Issue1145RegressionEnum, bool> status;
70+
}
71+
72+
@JsonSerializable(
73+
createFactory: false,
74+
)
75+
class Issue1145RegressionB {
76+
Issue1145RegressionB({
77+
required this.status,
78+
});
79+
80+
Map<String, dynamic> toJson() => _$Issue1145RegressionBToJson(this);
81+
82+
final List<Issue1145RegressionEnum?> status;
83+
}

json_serializable/test/integration/json_enum_example.g.dart

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

json_serializable/test/integration/json_test_example.g.dart

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)