Skip to content

copyWith generation #11

Description

@FatulM

Generate copyWith method for sealed classes.

We should disallow generic type change in copy with method to make life easier.

For nullable types we have two approaches:

For example:

class Base{
void one(int? x);
}

Freezes way of implementation:

this will generate code which needs two levels of inheritance for each copy with method and is not very straight forward.

we have this:

/// @nodoc
abstract class $BaseCopyWith<$Res> {
  factory $BaseCopyWith(Base value, $Res Function(Base) then) =
      _$BaseCopyWithImpl<$Res>;
}

/// @nodoc
class _$BaseCopyWithImpl<$Res> implements $BaseCopyWith<$Res> {
  _$BaseCopyWithImpl(this._value, this._then);

  final Base _value;

  // ignore: unused_field
  final $Res Function(Base) _then;
}

then this:

/// @nodoc
abstract class _$OneCopyWith<$Res> {
  factory _$OneCopyWith(_One value, $Res Function(_One) then) =
      __$OneCopyWithImpl<$Res>;

  $Res call({int? x});
}

/// @nodoc
class __$OneCopyWithImpl<$Res> extends _$BaseCopyWithImpl<$Res>
    implements _$OneCopyWith<$Res> {
  __$OneCopyWithImpl(_One _value, $Res Function(_One) _then)
      : super(_value, (v) => _then(v as _One));

  @override
  _One get _value => super._value as _One;

  @override
  $Res call({
    Object? x = freezed,
  }) {
    return _then(_One(
      x: x == freezed
          ? _value.x
          : x // ignore: cast_nullable_to_non_nullable
              as int?,
    ));
  }
}

we have this:

@JsonKey(ignore: true)
  _$OneCopyWith<_One> get copyWith => throw _privateConstructorUsedError;

which will be overriden by:

  @JsonKey(ignore: true)
  @override
  _$OneCopyWith<_One> get copyWith =>
      __$OneCopyWithImpl<_One>(this, _$identity);

And using optionals:

class Optional<T> {
  final bool isValid;
  final T? _value;

  T get value => _value as T;

  const Optional()
      : isValid = false,
        _value = null;
  const Optional.value(this._value) : isValid = true;
}

class Person {
  final String? name;

  Person(this.name);

  Person copyWith({Optional<String?> name = const Optional()}) =>
      Person(name.isValid ? name.value : this.name);
}

But when you want to set to any thing you should use optional ...

Special thanks to @iamarnas for his recommendations.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions