0

Even below code already check t.s!=null, dart still throws Error:

t.dart:7:26: Error: Property 'length' cannot be accessed on 'String?' because it is potentially null. Try accessing using ?. instead. if (t.s != null && t.s.length > 5) {}

class Test {
  String? s;
}

void main() {
  Test t = Test();
  if (t.s != null && t.s.length > 5) {}
}

Add extra var would solve it as below:

void main() {
  Test t = Test();
  var s = t.s;
  if (s != null && s.length > 5) {}
}

Why dart throws error even t.s!=null already checked?

Is there a way to do it without adding extra var?

Additionally, in Typescript, it won't throw error:

function main(t:{s?:string}){
  if(t.s!==undefined && t.s.length > 5){
  }
}
JasonHsieh
  • 553
  • 1
  • 6
  • 20
  • 1
    [Only local variables can be type-promoted](https://dart.dev/tools/non-promotion-reasons#property-or-this). – jamesdlin Dec 10 '22 at 04:55

2 Answers2

0

if you check t.s != null, after that you can safely convert it from String? to String. ( ! will convert you from String? to String )

void main() {
  Test t = Test();
  if (t.s != null && t.s!.length > 5) {}
}

https://dart.dev/null-safety/understanding-null-safety

“Casting away nullability” comes up often enough that we have a new shorthand syntax. A postfix exclamation mark (!) takes the expression on the left and casts it to its underlying non-nullable type."

rszf
  • 166
  • 1
  • 8
  • `t.s!.length > 5` would also work without `t.s != null`. Since we already checked `t.s != null`, dart should get enough information to skip the error on `t.s.length > 5`. Typescript can do it. I'm curious if dart really cannot do it like this. – JasonHsieh Dec 09 '22 at 10:00
  • it's checking in the second case, when you have the extra var. if you remove s!=null there, I will give an error.. – rszf Dec 09 '22 at 10:10
0

Since s is nullable, a subclass might change s to a getter that randomly returns either a null or a string. Thus, the analyzer correctly cannot type-promote s to non-null upon seeing t.s != null, because it might be null in the next expression. This is why copying it to a local variable works, because there's no chance of that any more.

I have a video on this: https://youtu.be/rqS_Q34RcUk

There's nothing to fix. There is a discussion on allowing a library-private class to permit this type promotion since it could not be overridden by unknown code.

Randal Schwartz
  • 39,428
  • 4
  • 43
  • 70