You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何创建通用响应模型?解决List与Map类型转换错误

解决Flutter中API响应data字段同时兼容Map和List的问题

你的问题核心是API返回的data字段类型不固定——时而是单个Map对象,时而是List集合,但现有响应模型把data硬编码成了Map<String, dynamic>?,导致解析List时触发类型转换异常。下面给出最优雅的泛型解决方案,同时兼顾类型安全和灵活性。

通用泛型响应模型

把原来的ApiResponseModel改成泛型类,让data的类型可以动态指定,同时通过回调函数处理具体的类型解析:

class ApiResponseModel<T> {
  final int statusCode;
  final String? status;
  final String? message;
  final T? data;

  ApiResponseModel({
    required this.statusCode,
    this.status,
    this.message,
    this.data,
  });

  // 从JSON解析,传入自定义的data转换回调
  factory ApiResponseModel.fromJson(
    Map<String, dynamic> json,
    T Function(dynamic data) convertData,
  ) {
    return ApiResponseModel<T>(
      statusCode: json['status_code'] as int,
      status: json['status'] as String?,
      message: json['message'] as String?,
      // 调用回调处理data的类型转换,兼容Map/List
      data: json['data'] != null ? convertData(json['data']) : null,
    );
  }

  // 转JSON,同样传入data的序列化回调
  Map<String, dynamic> toJson(Object Function(T? data) serializeData) {
    return {
      'status_code': statusCode,
      'status': status,
      'message': message,
      'data': data != null ? serializeData(data) : null,
    };
  }
}

实际使用示例

假设你有一个User实体类:

class User {
  final String userId;

  User({required this.userId});

  factory User.fromJson(Map<String, dynamic> json) {
    return User(userId: json['userID'] as String);
  }

  Map<String, dynamic> toJson() {
    return {'userID': userId};
  }
}

1. 解析List类型的响应(示例1的场景)

// 假设responseJson是接口返回的JSON Map
final apiResponse = ApiResponseModel<List<User>>.fromJson(
  responseJson,
  // 把List<dynamic>转成List<User>
  (data) => (data as List<dynamic>)
      .map((item) => User.fromJson(item as Map<String, dynamic>))
      .toList(),
);

// 之后可以安全地使用apiResponse.data(类型是List<User>?)

2. 解析Map类型的响应(示例2的场景)

final apiResponse = ApiResponseModel<User>.fromJson(
  responseJson,
  // 把Map<String, dynamic>转成User
  (data) => User.fromJson(data as Map<String, dynamic>),
);

// 此时apiResponse.data的类型是User?

为什么这个方案更好

  • 类型安全:编译时就能检查data的类型,避免运行时类型错误
  • 灵活性:不仅兼容Map和List,还能支持任意自定义类型的data
  • 解耦:响应模型不用关心具体的data结构,把解析逻辑交给外部回调,符合单一职责原则

内容的提问来源于stack exchange,提问作者Augustine Onu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:52:33