我有一个来自API的JSON数据结构,其中包含一些字段。
我想创建一个Freezed模型,它有一个工厂来创建正确的子类,这取决于其中一个字段的类型。
下面是我的代码:
abstract class ItineraryData<T> implements _$ItineraryData<T> {
const ItineraryData._();
const factory ItineraryData({
List<dynamic> summary,
double totalPrice,
double totalSeparatePay,
double totalTax,
List<String> covidAlerts,
}) = _ItineraryData;
const factory ItineraryData.flight({
List<FlightSummary> summary,
double totalPrice,
double totalSeparatePay,
double totalTax,
List<String> covidAlerts,
}) = _FlightItineraryData;
const factory ItineraryData.hotel({
List<HotelSummary> summary,
double totalPrice,
double totalSeparatePay,
double totalTax,
}) = _HotelItineraryData;
const factory ItineraryData.car({
List<CarSummary> summary,
double totalPrice,
double totalSeparatePay,
double totalTax,
List<String> covidAlerts,
}) = _CarItineraryData;
factory ItineraryData.fromJson(Map json) => _$ItineraryDataFromJson(json);
}在这种情况下,访问ItineraryData<A>的引用将永远不会有summary列表字段(它应该始终存在,但类型不同)。
然后,我尝试将未命名的构造函数更改为在列表类型中使用<T>:
const factory ItineraryData({
List<T> summary,
double totalPrice,
double totalSeparatePay,
double totalTax,
List<String> covidAlerts,
}) = _ItineraryData;但随后我得到了以下错误:
Could not generate `fromJson` code for `summary` because of type `T` (type parameter).
None of the provided `TypeHelper` instances support the defined type.
To support type paramaters (generic types) you can:
1) Use `JsonConverter`
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonConverter-class.html
2) Use `JsonKey` fields `fromJson` and `toJson`
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/fromJson.html
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonKey/toJson.html
3) Set `JsonSerializable.genericArgumentFactories` to `true`
https://pub.dev/documentation/json_annotation/latest/json_annotation/JsonSerializable/genericArgumentFactories.html
package:<???>/models/itinerary_data.freezed.dart:253:17
╷
253 │ final List<T> summary;
│ ^^^^^^^
╵
[INFO] Running build completed, took 221ms我确实尝试添加了一个转换器,如下所示:
class ItineraryDataConverter
implements JsonConverter<ItineraryData, Map<String, dynamic>> {
const ItineraryDataConverter();
@override
ItineraryData fromJson(Map<String, dynamic> json) {
if (json == null || !json.containsKey('data')) {
return null;
}
json = json['data'];
// type data was already set (e.g. because we serialized it ourselves)
if (!json.keys
.any((k) => ['cabin_class', 'hotel', 'car_type'].contains(k))) {
return ItineraryData.fromJson(json);
}
// you need to find some condition to know which type it is. e.g. check the presence of some field in the json
if (json.containsKey('cabin_class')) {
return _FlightItineraryData.fromJson(json);
} else if (json.containsKey('hotel')) {
return _HotelItineraryData.fromJson(json);
} else if (json.containsKey('car_type')) {
return _CarItineraryData.fromJson(json);
} else {
throw Exception(
'Could not determine the constructor for mapping from JSON');
}
}
@override
Map<String, dynamic> toJson(ItineraryData data) => data.toJson();
}但我仍然得到相同的错误。
如何确保summary在子类中是可见的、强类型的?
或者,对此更好的方法是什么?
发布于 2020-12-02 23:52:22
您是否尝试过为类型T添加自定义转换器
const factory ItineraryData({
@CustomConverter() List<T> summary,
...
...
class CustomConverter<T> implements JsonConverter<T, Object> {
const CustomConverter();
@override
T fromJson(Object json) {
// TODO: implement fromJson
throw UnimplementedError();
}
@override
Object toJson(T object) {
// TODO: implement toJson
throw UnimplementedError();
}
}https://stackoverflow.com/questions/65109738
复制相似问题