When I write nested generic freezed type, compiler puts errors.
My code is below.
Inner is a freezed class which has a generic type I.Outer is also a freezed class which contains a Inner<int>.inner.dart
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'inner.freezed.dart';
@freezed
abstract class Inner<I> with _$Inner<I> {
const factory Inner({
I data,
}) = _Inner<I>;
}
and outer.dart
import 'package:flutter/foundation.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:freezed_generics/inner.dart';
part 'outer.freezed.dart';
@freezed
abstract class Outer with _$Outer {
const factory Outer({
Inner<int> innerData,
}) = _Outer;
}
The code generation is succeeded. But generated code causes (four) errors.
error: The name 'I' isn't a type so it can't be used as a type argument. (non_type_as_type_argument at [freezed_generics] lib/outer.freezed.dart:36)
error: The name 'I' isn't a type so it can't be used as a type argument. (non_type_as_type_argument at [freezed_generics] lib/outer.freezed.dart:57)
error: The name 'I' isn't a type so it can't be used as a type argument. (non_type_as_type_argument at [freezed_generics] lib/outer.freezed.dart:61)
error: The name 'I' isn't a type so it can't be used as a type argument. (non_type_as_type_argument at [freezed_generics] lib/outer.freezed.dart:74)
When I replace above I to int in generated outer.freezed.dart manually, the code seems to work fine. Is this expected behavior? Do I missed some usages? (I'm new to Dart and Flutter :pray: )
I attached a reproduction project (as zip file).
Thanks for great package! :heart: :heart:
Thanks for the report!
It looks like a bug. I'll investigate
I've pin-pointed the problem and know the fix.
But to make the fix, I need an extra information: the generic parameters passed to the object (int for List<int>)
Sadly, I don't see any way to obtain this information.
Actually I found the solution through luck
Hi @rrousselGit
I also have the issue.
Could not generate `fromJson` code for `data` 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:melodyo/domain/core/response.freezed.dart:152:11
and my freezed class is:
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:json_annotation/json_annotation.dart';
part 'response.freezed.dart';
part 'response.g.dart';
@freezed
abstract class Response<T> with _$Response<T> {
const factory Response({
T data,
String message,
Map<String, dynamic> errors,
Map<String, dynamic> links,
Map<String, dynamic> meta,
}) = _Response<T>;
factory Response.fromJson(Map<String, dynamic> json) =>
_$ResponseFromJson(json);
}
There is no way to deserialize T, because that could be anything.
Either use a Converter (see https://github.com/rrousselGit/freezed#fromjson---classes-with-multiple-constructors), or change how you model your data to not rely on generics.
Maybe change your Response to:
@freezed
abstract class Response<T> with _$Response<T> {
const factory Response({
Map<String, Object> data,
String message,
Map<String, Object> errors,
Map<String, Object> links,
Map<String, Object> meta,
}) = _Response<T>;
factory Response.fromJson(Map<String, Object> json) =>
_$ResponseFromJson(json);
}
and deserialize data separately.
Hi @rrousselGit
Ok, the data could be a Map or a List or anything else.
I will deserialize data separately but hope you find a way to deserialize generic types.
Thanks.
That's simply not feasible
Most helpful comment
Thanks for the report!
It looks like a bug. I'll investigate