📝

【Flutter】Dartのtype promotionについて

に公開

発生した内容について

私は今まで

if(value != null){
   print(value);
}

のように、null チェックを実施した後は、その変数は「null ではないもの」として扱えるのだと思っていました。

しかし実際には、次のように書かないと警告が出る場合があります。

if(value != null){
  print(value!);
}

同じように null チェックしているのに、value は OK なケースと value! を付けないと警告になるケースがありました。この違いが気になったので、今回きちんと調べてみました。

いろんなパターンで検証

このような「条件分岐を元に、より狭い型として扱う」仕組みは type promotion(型プロモーション) と呼ばれます。
Fixing type promotion failuresという公式ドキュメントを参考に見ていきます。

まずStatelessWidgetのフィールドでまず試してみましょう。

class MyWidget extends StatelessWidget {
 MyWidget(
   this.a,
   this._b,
   this._c,
 );
 final int? a;
 int? _b;
 final int? _c;

 
 Widget build(BuildContext context) {
   if (a != null) {
     a!.isEven;
   }
   if (_b != null) {
     _b!.isEven;
   }
   if (_c != null) {
     _c.isEven;
   }
   return const Placeholder();
 }
}

final int? _cのように、privateなフィールドかつfinalであればtype promotionが可能のようです。
ローカル変数の場合はtype promotionはされるので、今回のケースでも

   final localA = a;
   if (localA != null) {
     localA.isEven;
   }

のようにローカル変数に格納することで、対応することも可能です。

Discussion