解决json_annotation生成.g文件的List<dynamic>转List<APIIngredients>错误
问题现象
使用json_annotation包生成.g文件后,运行应用时出现类型不匹配错误:
Error: The argument type 'List
' can't be assigned to the parameter type 'List '.
手动修改生成文件recipe_model.g.dart中_$APIRecipeFromJson方法的dynamic为APIIngredients后,又出现新错误:
Unhandled Exception: type 'List
' is not a subtype of type 'List ' in type cast
问题原因
生成的_$APIRecipeFromJson方法中,ingredients字段仅直接将json['ingredients']作为List<dynamic>赋值,未将列表内的每个元素转换为APIIngredients实例。同时,Dart不允许直接将List<dynamic>强转为List<APIIngredients>,必须逐个元素转换。此外,APIRecipe类的toJson方法定义错误,导致代码生成工具无法正确识别列表类型的转换规则。
解决方案
1. 修复模型类的toJson方法错误
在APIRecipe类中,原toJson方法返回的是函数引用而非调用结果,修改为:
@JsonSerializable() class APIRecipe { // ... 其他字段和构造函数 // 修正后的toJson方法 Map<String, dynamic> toJson() => _$APIRecipeToJson(this); // ... 其他方法 }
2. 重新生成代码
在终端执行代码生成命令,覆盖原有的.g文件:
# 先清理旧的生成文件(可选) flutter pub run build_runner clean # 重新生成代码 flutter pub run build_runner build
验证生成结果
重新生成后的_$APIRecipeFromJson方法中,ingredients字段会自动生成正确的转换逻辑:
APIRecipe _$APIRecipeFromJson(Map<String, dynamic> json) => APIRecipe( label: json['label'].toString(), image: json['image'].toString(), url: json['url'].toString(), ingredients: (json['ingredients'] as List<dynamic>) .map((e) => APIIngredients.fromJson(e as Map<String, dynamic>)) .toList(), calorie: (json['calorie'] as num).toDouble(), totalWeight: (json['totalWeight'] as num).toDouble(), totalTime: (json['totalTime'] as num).toDouble(), );
这段代码会遍历json['ingredients']的每个元素,通过APIIngredients.fromJson转换为目标类型,最终得到List<APIIngredients>。
注意事项
- 不要手动修改生成的
.g文件,每次运行build_runner都会覆盖这些文件,必须通过修正模型类代码让工具自动生成正确逻辑。
内容的提问来源于stack exchange,提问作者joseph Ofori Tenkorang

