如何在Dart中正确映射泛型基础模型BaseResponse的Result属性
解决Dart泛型BaseResponse的JSON映射问题
当前自定义的BaseResponse<T>泛型模型无法将JSON中的result字段正确映射为复杂模型(如嵌套AddressModel的SampleModel)或简单类型(如String),核心问题在于Dart泛型的类型擦除机制,导致fromJson无法自动推断并解析泛型类型。
1. 修改BaseResponse的fromJson方法,添加类型解析回调
Dart运行时会擦除泛型类型信息,因此需要在fromJson中传入自定义解析函数,用来将json['result']转换为目标类型T。
修改后的BaseResponse代码:
class BaseResponse<T> { final bool error; final String? message; final T? result; const BaseResponse({required this.error, this.message, this.result}); // 添加解析T的回调函数参数 factory BaseResponse.fromJson( Map<String, dynamic> json, T Function(dynamic) fromJsonT, ) { final bool error = json['error'] as bool; final String? message = json['message'] as String?; // 使用传入的解析函数处理result final T? result = json['result'] != null ? fromJsonT(json['result']) : null; return BaseResponse(error: error, message: message, result: result); } }
2. 为复杂模型添加fromJson方法
对于SampleModel和AddressModel这类嵌套模型,需要各自实现fromJson工厂方法来完成嵌套解析:
class AddressModel { final String street; final String city; AddressModel({required this.street, required this.city}); factory AddressModel.fromJson(Map<String, dynamic> json) { return AddressModel( street: json['street'] as String, city: json['city'] as String, ); } } class SampleModel { final String firstName; final String lastName; final AddressModel address; SampleModel({required this.firstName, required this.lastName, required this.address}); factory SampleModel.fromJson(Map<String, dynamic> json) { return SampleModel( firstName: json['firstName'] as String, lastName: json['lastName'] as String, // 解析嵌套的AddressModel address: AddressModel.fromJson(json['address'] as Map<String, dynamic>), ); } }
3. 调用示例(复杂类型+简单类型)
在HTTP请求回调中,根据result的目标类型传入对应的解析函数:
解析复杂类型(SampleModel)
import 'dart:convert'; import 'package:http/http.dart' as http; void main() { Future<void> getResponse() async { final response = await http.get(Uri.parse('https://getsomething.com')); // 检查响应状态等逻辑 if (response.statusCode == 200) { final jsonData = jsonDecode(response.body) as Map<String, dynamic>; // 传入SampleModel.fromJson作为解析函数 final baseResponse = BaseResponse<SampleModel>.fromJson( jsonData, (data) => SampleModel.fromJson(data as Map<String, dynamic>), ); // 使用baseResponse.result(类型为SampleModel?) print(baseResponse.result?.firstName); } } getResponse(); }
解析简单类型(如String)
如果result是简单类型,直接传入类型转换逻辑即可:
final baseResponse = BaseResponse<String>.fromJson( jsonData, (data) => data as String, );
内容的提问来源于stack exchange,提问作者Jeremy Trpka
相关产品推荐
相关产品推荐

