There are multiple options:
1. ValueGetter
class B {
const B();
}
class A {
const A({
this.nonNullable = const B(),
this.nullable,
});
final B nonNullable;
final B? nullable;
A copyWith({
B? nonNullable,
ValueGetter<B?>? nullable,
}) {
return A(
nonNullable: nonNullable ?? this.nonNullable,
nullable: nullable != null ? nullable() : this.nullable,
);
}
}
const A().copyWith(nullable: () => null);
const A().copyWith(nullable: () => const B());
2. Optional from Quiver package
class B {
const B();
}
class A {
const A({
this.nonNullable = const B(),
this.nullable,
});
final B nonNullable;
final B? nullable;
A copyWith({
B? nonNullable,
Optional<B>? nullable,
}) {
return A(
nonNullable: nonNullable ?? this.nonNullable,
nullable: nullable != null ? nullable.value : this.nullable,
);
}
}
const A().copyWith(nullable: const Optional.fromNullable(null));
const A().copyWith(nullable: const Optional.fromNullable(B()));
3. copyWith as field
class _Undefined {}
class B {
const B();
}
class A {
A({
this.nonNullable = const B(),
this.nullable,
});
final B nonNullable;
final B? nullable;
// const constructor no more avaible
late A Function({
B? nonNullable,
B? nullable,
}) copyWith = _copyWith;
A _copyWith({
B? nonNullable,
Object? nullable = _Undefined,
}) {
return A(
nonNullable: nonNullable ?? this.nonNullable,
nullable: nullable == _Undefined ? this.nullable : nullable as B?,
);
}
}
A().copyWith(nullable: null);
A().copyWith(nullable: const B());
4. copyWith redirected constructor
class _Undefined {}
class B {
const B();
}
abstract class A {
const factory A({
B nonNullable,
B? nullable,
}) = _A;
const A._({
required this.nonNullable,
this.nullable,
});
final B nonNullable;
final B? nullable;
A copyWith({B? nonNullable, B? nullable});
}
class _A extends A {
const _A({
B nonNullable = const B(),
B? nullable,
}) : super._(nonNullable: nonNullable, nullable: nullable);
@override
A copyWith({B? nonNullable, Object? nullable = _Undefined}) {
return _A(
nonNullable: nonNullable ?? this.nonNullable,
nullable: nullable == _Undefined ? this.nullable : nullable as B?,
);
}
}
const A().copyWith(nullable: null);
const A().copyWith(nullable: const B());
5. copyWith redirected constructor 2
class _Undefined {}
class B {
const B();
}
abstract class A {
const factory A({
B nonNullable,
B? nullable,
}) = _A;
const A._();
B get nonNullable;
B? get nullable;
A copyWith({B? nonNullable, B? nullable});
}
class _A extends A {
const _A({
this.nonNullable = const B(),
this.nullable,
}) : super._();
@override
final B nonNullable;
@override
final B? nullable;
@override
A copyWith({B? nonNullable, Object? nullable = _Undefined}) {
return _A(
nonNullable: nonNullable ?? this.nonNullable,
nullable: nullable == _Undefined ? this.nullable : nullable as B?,
);
}
}
const A().copyWith(nullable: null);
const A().copyWith(nullable: const B());