🧊

freezedの名前付き引数の型定義は要注意

に公開

はじめに

Flutter/Dartでimmutableなデータクラスを生成する際によく使用されるfreezedパッケージ。
今回は、freezedを使用する際に発生した警告(unnecessary_non_null_assertionの)の解決方法について、自分用のメモとして本記事を執筆しました。

問題の状況

以下のようなコードでfuga.freezed.dartを生成した際、analyzerunnecessary_non_null_assertionの警告を発生させました。

// fuga.dart

typedef Hoge = Map<String, dynamic>;


abstract class Fuga with _$Fuga {
  const factory Fuga({
    required Hoge json,
  }) = _Fuga;
}

警告の原因

生成されたfuga.freezed.dartを確認すると、以下のようなコードが生成されていました。

// fuga.freezed.dart

Fuga get json;

('vm:prefer-inline')  $Res call({Object? json = null,}) {
    return _then(_self.copyWith(
        json: null == json ? _self.json! : json // ignore: cast_nullable_to_non_nullable
        as Map<String, dynamic>,
    ));
}

問題は、生成されたコードでjsonプロパティに対して!演算子(non-null assertion operator)が使用されていることです。これはunnecessary_non_null_assertion警告の原因となります。

解決方法

この問題を解決するには、名前付き引数の型定義にtypedefで定義した独自の型を使用せず、SDK標準の型を直接使用します。

// fuga.dart


abstract class Fuga with _$Fuga {
  const factory Fuga({
    required Map<String, dynamic> json,
  }) = _Fuga;
}

この変更により、生成されるコードは以下のようになり、警告が解消されます。

// fuga.freezed.dart

Map<String, dynamic> get json;

('vm:prefer-inline')  $Res call({Object? json = null,}) {
    return _then(_self.copyWith(
        json: null == json ? _self.json : json // ignore: cast_nullable_to_non_nullable
        as Map<String, dynamic>,
    ));
}

なぜこの解決方法が有効なのか

partpart ofでコード連携しているため、fuga.freezed.dartFugaクラスを参照できます。しかし、build_runnertypedefを考慮せずにコードを生成するため、不必要な!演算子が生成されてしまいます。

名前付き引数の型定義には、必ずSDK標準の型を使用することで、この問題を回避できます。

まとめ

freezedを使用する際に名前付きの型を定義する場合は、以下の点に注意しましょう:

  1. typedefで定義した独自の型は使用せず、SDK標準の型を直接使用する
  2. 特に名前付き引数の型定義では、このルールを厳守する

これにより、不要な警告を防ぎ、よりクリーンなコードを維持することができます。

GitHubで編集を提案
株式会社ゆめみ

Discussion