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

禁用嵌套Freezed对象copyWith致构建失败的解决问询

Freezed嵌套对象禁用copyWith导致构建失败的解决办法

问题场景

当使用Freezed创建嵌套对象时,若给内层对象BlocScreenNavigator禁用copyWith,外层的RenewLeaseState自动生成的copyWith代码会尝试调用内层对象的copyWith相关类型和方法,导致构建失败。

代码示例:

@freezed
class RenewLeaseState with _$RenewLeaseState {
  const factory RenewLeaseState({
    @Default(BlocScreenNavigator()) BlocScreenNavigator navigator,
  }) = _RenewLeaseState;
}

@Freezed(copyWith: false)
class BlocScreenNavigator with _$BlocScreenNavigator {
  const factory BlocScreenNavigator({
    @Default(RenewLeaseScreen.init) RenewLeaseScreen screen,
    @Default(false) bool isPop,
  }) = _BlocScreenNavigator;
}

报错信息

lib/renew_lease/cubit/renew_lease_cubit.freezed.dart:56:3: Error: Type '$BlocScreenNavigatorCopyWith' not found.
$BlocScreenNavigatorCopyWith<$Res> get navigator;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/renew_lease/cubit/renew_lease_cubit.freezed.dart:116:3: Error: Type '$BlocScreenNavigatorCopyWith' not found.
$BlocScreenNavigatorCopyWith<$Res> get navigator {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/renew_lease/cubit/renew_lease_cubit.freezed.dart:142:3: Error: Type '$BlocScreenNavigatorCopyWith' not found.
$BlocScreenNavigatorCopyWith<$Res> get navigator;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
lib/renew_lease/cubit/renew_lease_cubit.freezed.dart:117:12: Error: The method '$BlocScreenNavigatorCopyWith' isn't defined for the class '_$RenewLeaseStateCopyWithImpl<$Res>'.

  • '_$RenewLeaseStateCopyWithImpl' is from 'package:tenant_app/renew_lease/cubit/renew_lease_cubit.dart' ('lib/renew_lease/cubit/renew_lease_cubit.dart'). Try correcting the name to the name of an existing method, or defining a method named '$BlocScreenNavigatorCopyWith'.
    return $BlocScreenNavigatorCopyWith<$Res>(_value.navigator, (value) {
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    FAILURE: Build failed with an exception.

原因分析

这是Freezed的已知未解决问题,外层类自动生成copyWith时,默认会为嵌套的Freezed对象生成链式调用的copyWith逻辑,但内层对象禁用copyWith后,相关的$XXXCopyWith类型和方法不会生成,导致外层代码找不到依赖,编译报错。

解决办法

方案1:手动实现外层类的copyWith方法

给外层类RenewLeaseState添加@Freezed(copyWith: false),然后手动实现需要的copyWith逻辑,避免自动生成的代码调用内层对象的copyWith:

@Freezed(copyWith: false)
class RenewLeaseState with _$RenewLeaseState {
  const factory RenewLeaseState({
    @Default(BlocScreenNavigator()) BlocScreenNavigator navigator,
  }) = _RenewLeaseState;

  // 手动实现copyWith,按需处理字段
  RenewLeaseState copyWith({
    BlocScreenNavigator? navigator,
  }) {
    return RenewLeaseState(
      navigator: navigator ?? this.navigator,
    );
  }
}

@Freezed(copyWith: false)
class BlocScreenNavigator with _$BlocScreenNavigator {
  const factory BlocScreenNavigator({
    @Default(RenewLeaseScreen.init) RenewLeaseScreen screen,
    @Default(false) bool isPop,
  }) = _BlocScreenNavigator;
}

方案2:将内层对象改为手动实现的不可变类

放弃用Freezed生成BlocScreenNavigator,手动编写不可变类并禁用copyWith,这样外层类生成copyWith时只会直接赋值对象,不会尝试调用其copyWith:

@freezed
class RenewLeaseState with _$RenewLeaseState {
  const factory RenewLeaseState({
    @Default(BlocScreenNavigator()) BlocScreenNavigator navigator,
  }) = _RenewLeaseState;
}

// 手动实现不可变类,不提供copyWith
class BlocScreenNavigator {
  final RenewLeaseScreen screen;
  final bool isPop;

  const BlocScreenNavigator({
    this.screen = RenewLeaseScreen.init,
    this.isPop = false,
  });

  // 不实现copyWith,强制用户手动创建新对象
}

方案3:使用Freezed的@CustomCopyWith自定义逻辑

通过@CustomCopyWith注解,为外层类的navigator字段自定义copy处理逻辑,避免自动生成链式copyWith:

@freezed
class RenewLeaseState with _$RenewLeaseState {
  const factory RenewLeaseState({
    @Default(BlocScreenNavigator()) 
    @CustomCopyWith(
      resolver: _navigatorCopyWithResolver,
    )
    BlocScreenNavigator navigator,
  }) = _RenewLeaseState;
}

// 自定义copyWith解析器,直接返回传入的对象或原对象
T _navigatorCopyWithResolver<T>(T value, T? Function(T) updates) {
  return updates(value) ?? value;
}

@Freezed(copyWith: false)
class BlocScreenNavigator with _$BlocScreenNavigator {
  const factory BlocScreenNavigator({
    @Default(RenewLeaseScreen.init) RenewLeaseScreen screen,
    @Default(false) bool isPop,
  }) = _BlocScreenNavigator;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:15:44