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

能否利用已有Freezed数据类构建Union类型?

如何用Freezed复用已有数据类构建通用Union类型

这确实是个很实用的需求——没人想每次定义新的接口返回结果类型时,都重复写一遍ApiFailure的case,更怕后续修改ApiFailure结构时要到处找地方改。好在Freezed完全支持复用已有的数据类来构建通用的Union类型,这里给你两个最适合的方案:

方案一:创建泛型ApiResult(最推荐)

我们可以定义一个带泛型的ApiResult Union,把ApiFailure作为通用的失败case,成功case则用泛型接收任意你已经定义好的Model(比如ModelA、ModelB),这样完全不用重复关联ApiFailure:

import 'package:freezed_annotation/freezed_annotation.dart';

part 'api_result.freezed.dart';

@freezed
abstract class ApiResult<T> with _$ApiResult<T> {
  // 直接复用已有的ApiFailure类,作为失败状态
  const factory ApiResult.failure(ApiFailure failure) = ApiResultFailure<T>;
  
  // 用泛型接收任意成功模型,复用你已有的ModelA、ModelB
  const factory ApiResult.success(T data) = ApiResultSuccess<T>;
}

用法示例

现在你可以这样定义接口结果变量:

// 对应ModelA的接口结果
final ApiResult<ModelA> apiResult1;
// 对应ModelB的接口结果
final ApiResult<ModelB> apiResult2;

在Widget的builder里用fold处理时,写法和你之前用dartz的Either几乎一致:

return apiResult1.fold<Widget>(
  (failure) => ErrorWidget(failure), // failure就是你已定义的ApiFailure实例
  (data) => SuccessWidget(data), // data就是ModelA实例
);

这个方案的核心优势就是ApiFailure只需要维护一次,后续不管是加字段还是改结构,所有用到ApiResult的地方都会自动同步,完全不用逐个修改不同的ApiResult类型。

方案二:针对特殊场景的自定义Union(可选)

如果你的业务场景里,某个接口的返回结果除了Failure和Success,还有其他特殊状态(比如Loading、Empty),也可以基于已有的数据类扩展,但依然复用ApiFailure:

@freezed
abstract class SpecialApiResult with _$SpecialApiResult {
  // 复用已有的ApiFailure
  const factory SpecialApiResult.failure(ApiFailure failure) = _SpecialFailure;
  // 复用已有的ModelC
  const factory SpecialApiResult.success(ModelC data) = _SpecialSuccess;
  // 自定义额外状态
  const factory SpecialApiResult.loading() = _SpecialLoading;
}

这种方式适合有特殊状态需求的场景,但依然保证ApiFailure只被引用一次,避免重复维护。

你之前写法的问题说明

你之前尝试的const factory ApiResult1.modelA() = ModelA;其实不符合Freezed的语法——Freezed的factory如果要关联已有的类,需要把该类作为参数传入(比如上面的failure(ApiFailure failure)),而不是直接把factory指向已有的类。直接赋值会导致Freezed尝试生成一个和ModelA同名的新类,而不是复用你已有的ModelA,这也是为什么你会觉得无法复用的原因。

内容的提问来源于stack exchange,提问作者Abhilash Chandran

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 10:32:36