🔨

freezed 3.0.3 freezed 3.0.2 @overrideが必要?

2025/03/02に公開

factoryがいらなくなったが?

https://pub.dev/packages/freezed

🧪Xの投稿を見て気になり試してみた!

In Freezed, I always find it difficult to create a field for the class using a factory constructor. Now, in Freezed 3.0, you can no longer do that. Instead, you can use a normal constructor to create a freezed class. This makes it really easy to migrate any non-freezed class to a freezed class.

Freezed では、ファクトリ コンストラクターを使用してクラスのフィールドを作成するのが常に困難でした。Freezed 3.0 では、それができなくなりました。代わりに、通常のコンストラクターを使用して、フリーズされたクラスを作成できます。これにより、フリーズされていないクラスをフリーズされたクラスに移行するのが非常に簡単になります。

https://x.com/burhanrashid52/status/1894748455072923714/photo/1

使ってみるか

あれ「ニョロニョロ」が出てきた???

Lintの警告が出てくるぞ?

@overrideつけると消える?

Github isseusを見てみた。議論されている?
https://github.com/rrousselGit/freezed/issues/1176

既存の例や記事から、どのようなシナリオが見えてこないと思いますか?
説明してほしい問題の明確で簡潔な説明。

Classicクラスのスタイルでは、メンバ変数の宣言部分でannotate_overridesの警告が発生します。ファイルに // ignore_for_file: annotate_overrides を記述するか、手動でメンバ変数に @override アノテーションを追加する必要がありますか?
invalid_annotation_targetについては、明確なドキュメントがあります。annotate_overridesのドキュメントも参考になると思います。

既存の例や記事がこのケースをカバーしていない理由を説明してください。
この要望を出す前に、どの例や記事を見たか、そしてなぜそれがあなたの悩みの解決に役立たなかったかを説明してください。
なぜそれらがあなたの問題の助けにならなかったのかを説明してください。

以下のコードでは、メンバ変数 firstName, lastName, age で annotate_overrides の警告が発生しています。


オーバーライドは「一種の必要性」である。
mixinはこれらのフィールドを再定義し、==/toStringとcoがそれらにアクセスできるようにします。そのため、Dartはあなたの定義をオーバーライドだと勘違いしてしまいます。

それを修正するためには(@JsonSerializable()を削除するのと一緒に)拡張が必要だ。

他にも不具合がその他多数あるのか。。。

https://github.com/rrousselGit/freezed/issues/1184
https://github.com/rrousselGit/freezed/issues/1181
https://github.com/rrousselGit/freezed/issues/1178


ライブラリを追加してコマンドを実行してみた。

add freezed:

flutter pub add \
  freezed \
  freezed_annotation \
  --dev build_runner \
  --dev json_annotation \
  --dev json_serializable

generate:

flutter pub run build_runner watch --delete-conflicting-outputs

example

ダミーのデータを表示するコード。

main.dart
import 'package:flutter/material.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
part 'main.freezed.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
      ),
      home: const MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}


class Person with _$Person {
  
  final String name;
  
  final int age;

  Person({
    required this.name,
    required this.age,
  });
}

final persons = <Person>[
  Person(name: '山田太郎', age: 30),
  Person(name: '山田花子', age: 25),
];

class MyHomePage extends StatefulWidget {
  const MyHomePage({super.key, required this.title});

  final String title;

  
  State<MyHomePage> createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;

  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,

        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            const Text('You have pushed the button this many times:'),
            Text(
              '$_counter',
              style: Theme.of(context).textTheme.headlineMedium,
            ),
            Expanded(
              child: ListView.builder(
                itemCount: persons.length,
                itemBuilder: (context, index) {
                  final person = persons[index];
                  return ListTile(
                    title: Text(person.name),
                    subtitle: Text("年齢: ${person.age}"),
                  );
                },
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: const Icon(Icons.add),
      ),
    );
  }
}

使ってみた感想

使うことはできるがバージョンアップで仕組みが変わってしまったのか今後は、アプリのfreezedを新しくしたときに問題が出てきそうだ。慎重に対応することが求められそうです。

Discussion