copy_with_extension_gen 7.0.0
copy_with_extension_gen: ^7.0.0 copied to clipboard
Automatically generating `copyWith` extensions code for classes with `@CopyWith()` annotation.
This package provides a builder for the Dart Build System that generates copyWith extensions for classes annotated with copy_with_extension. For a detailed explanation of how this package works, check out my blog article.
This library lets you copy immutable objects and change individual fields as follows:
myInstance.copyWith.fieldName("test") // Change a single field.
myInstance.copyWith(fieldName: "test", anotherField: "test", nullableField: null) // Change multiple fields at once.
myInstance.copyWithNull(fieldName: true, anotherField: true) // Nullify multiple fields at once.
Usage #
In your pubspec.yaml file
- Add to
dependenciessectioncopy_with_extension: ^7.0.0 - Add to
dev_dependenciessectioncopy_with_extension_gen: ^7.0.0 - Add to
dev_dependenciessectionbuild_runner: ^2.1.7 - Set
environmentto at least Dart3.0.0version like so:">=3.0.0 <4.0.0"
Your pubspec.yaml should look like this:
environment:
sdk: ">=3.0.0 <4.0.0"
dependencies:
...
copy_with_extension: ^7.0.0
dev_dependencies:
...
build_runner: ^2.1.7
copy_with_extension_gen: ^7.0.0
Annotate your class with CopyWith annotation
import 'package:copy_with_extension/copy_with_extension.dart';
part 'basic_class.g.dart';
@CopyWith()
class BasicClass {
final String id;
final String? text;
const BasicClass({ required this.id, this.text});
}
Make sure that you set the part file as shown in the example above: part 'your_file_name.g.dart';.
Launch code generation
flutter pub run build_runner build
Use
const result = BasicClass(id: "id");
final copiedOne = result.copyWith.text("test"); // Results in BasicClass(id: "id", text: "test");
final copiedTwo = result.copyWith(id: "foo", text: null); // Results in BasicClass(id: "foo", text: null);
Additional features #
Change Multiple Fields Simultaneously
Modify several fields at once with the copyWith() function:
myInstance.copyWith(fieldName: "test", anotherField: "test");
Nullifying instance fields
Generate a copyWithNull function to nullify class fields. Enable this by setting copyWithNull to true:
@CopyWith(copyWithNull: true)
class MyClass {
...
}
Protect Immutable Fields
Prevent modification of specific fields by using:
@CopyWithField(immutable: true)
final int myImmutableField;
This enforces that the copyWith method copies this field without allowing modifications.
Custom Constructor Name
Set constructor if you want to use a named constructor, e.g. a private one. The generated fields will be derived from this constructor.
@CopyWith(constructor: "_")
class SimpleObjectPrivateConstructor {
@CopyWithField(immutable: true)
final String? id;
final int? intValue;
const SimpleObjectPrivateConstructor._({this.id, this.intValue});
}
Skipping generation of copyWith functionality for individual fields
Set skipFields to prevent the library from generating copyWith functions for individual fields e.g. instance.copyWith.id("123"). If you want to use only copyWith(...) function.
@CopyWith(skipFields: true)
class SimpleObject {
final String id;
final int? intValue;
const SimpleObject({required this.id, this.intValue});
}
build.yaml configuration
You can globally configure the library's behavior in your project by adding a build.yaml file. This allows you to customize features such as copyWithNull and skipFields globally across your project.
targets:
$default:
builders:
copy_with_extension_gen:
enabled: true
options:
copy_with_null: true # Default is false. Generate `copyWithNull` functions.
skip_fields: true # Default is false. Prevent generation of individual field methods, e.g. `instance.copyWith.id("123")`.
How is this library better than freezed? #
This package is a lightweight alternative for those who only need the copyWith functionality and prefer to keep their classes framework agnostic. You simply annotate your class with CopyWith() and specify the .part file. freezed provides many additional features but requires you to structure your models in a framework‑specific way.