🐕
freezedのモデルに共通利用するメソッドを拡張する
下記のようなcreatedAt
, updatedAt
があるfreezedのモデルに対して、formattedCreatedAtString
, formattedUpdatedAtString
の実装を共通化する場合、下記のように BaseModel
クラスを定義/implementsして、 BaseModel
のextension
で実装すると動く。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'freezed_model.freezed.dart';
class FreezedModel with _$FreezedModel implements BaseModel {
const FreezedModel._();
factory FreezedModel({
required String id,
required DateTime createdAt,
required DateTime updatedAt,
}) = _FreezedModel;
}
abstract class BaseModel {
const BaseModel();
DateTime get createdAt;
DateTime get updatedAt;
}
extension BaseModelEx on BaseModel {
String get formattedCreatedAtString => createdAt.formattedString(format: 'yyyy/MM/dd(E)');
String get formattedUpdatedAtString => updatedAt.formattedString(format: 'yyyy/MM/dd(E)');
}
extension DateTimeEx on DateTime {
String formattedString({String format = 'yyyy/MM/dd(E) HH:mm'}) {
final formatter = DateFormat(format, 'ja_JP');
final formattedString = formatter.format(this);
return formattedString;
}
}
ビルドエラーになるパターン
下記のようmixinにすると、freezedのモデルだとビルドエラーになる。
import 'package:freezed_annotation/freezed_annotation.dart';
part 'freezed_model.freezed.dart';
class FreezedModel with _$FreezedModel, BaseModelMixin {
factory FreezedModel({
required String id,
required DateTime createdAt,
required DateTime updatedAt,
}) = _FreezedModel;
}
mixin BaseModelMixin {
void printName(String name) {
print(name);
}
}
ビルドエラー
Error: The non-abstract class '_$_FreezedModel' is missing implementations for these members:
- BaseModelMixin.printName
Try to either
- provide an implementation,
- inherit an implementation from a superclass or mixin,
- mark the class as abstract, or
- provide a 'noSuchMethod' implementation.
Discussion