easy_copy_with

pub package License

Code generator for automatic copyWith methods in Dart classes using the @CopyWith annotation from easy_copy_with_annotation.

Installation

dependencies:
  easy_copy_with_annotation: 1.0.0

dev_dependencies:
  easy_copy_with: 5.0.0
  build_runner: 2.16.1

Quick Start

import 'package:easy_copy_with_annotation/easy_copy_with_annotation.dart';

part 'user.g.dart';

@CopyWith()
class User {
  final String name;
  final int age;
  final String? email;

  const User({required this.name, required this.age, this.email});
}

Generate code:

dart run build_runner build

Use:

final user = User(name: 'John', age: 30);
final olderUser = user.copyWith(age: 31);
final withoutEmail = user.copyWith(email: null); // nullable fields supported

Features

  • Annotation-based API
  • Statically typed generated API
  • Supports nullable and non-nullable fields
  • Supports generic type parameters
  • Supports sealed classes
  • Supports named constructors

Sealed Classes

@CopyWith()
sealed class Role {
  const factory Role.admin({required int adminLevel}) = Admin;
  const factory Role.userRole({required String username}) = UserRole;
  const Role._();
}

final class Admin extends Role {
  final int adminLevel;
  const Admin({required this.adminLevel}) : super._();
}

final class UserRole extends Role {
  final String username;
  const UserRole({required this.username}) : super._();
}

Migration from 3.x

  1. Add easy_copy_with_annotation: 1.0.0 to dependencies
  2. Move easy_copy_with to dev_dependencies
  3. Replace imports:
    • import 'package:easy_copy_with/annotations.dart' -> import 'package:easy_copy_with_annotation/easy_copy_with_annotation.dart'
    • import 'package:easy_copy_with/easy_copy_with.dart' -> import 'package:easy_copy_with_annotation/easy_copy_with_annotation.dart'

Migration from 4.x

  • Upgrade to Dart 3.11 or newer. Version 5 uses analyzer 14.4.0 and source_gen 4.3.0; other generators in your application must support these versions. Dependency versions are pinned in the package manifest.
  • Keep easy_copy_with_annotation at 1.0.0 and regenerate your .g.dart files.
  • Generic bounds, nullable type arguments, and dynamic fields are supported. Passing null clears a nullable value; omitting an argument preserves it.
  • Shared copyWith parameters on sealed classes now include inherited fields accepted by every variant's constructor.

Constructor and sealed-class requirements

The generator selects a public unnamed generative constructor, or the first public named generative constructor. Each parameter must have a readable instance getter with the same name and a compatible type, including inherited getters. Unsupported constructors produce a generation error with the class and parameter name.

Sealed dispatch requires a closed hierarchy of constructible concrete variants. Generic variant parameters must map directly to parameters of the sealed base. Annotate only the sealed root; its variants are generated automatically. Fields that are not accepted by every variant's constructor are available only on the relevant concrete type's copyWith.

License

MIT

Libraries

easy_copy_with