Type Check Level: strict causes Cannot find symbol ':data' on type 'Null'

Wen I set the Type Check Level to strinct then the following code doesn't compile:

if (sensor != null && sensor.data != null) {...}

Type Check Level: strict causes Cannot find symbol ':data' on type 'Null'

How am I supposed to deal with these? Is there a better solution than the too verbose casting:

if (sensor != null && (sensor as Sensor).data != null) {...}

The compiler must be clever enough to figure it out that sensor can't be null there, or at least we should have the ! operator like in kotlin:

if (sensor != null && sensor!.data != null) {...}

  • s.hrOption =

    Not sure what your point is? I *said* that version works. Its the && version that doesn't. said this month's sdk update would fix the && version. If you were suggesting that the parentheses make a difference there, I'm pretty sure they don't - ie it works with or without them, and means the same thing.

  • no, he was saying that the && still doesn't work even though SDK 4.1.4 was released.

  • I can confirm this fix is not in 4.1.4, but will be in an upcoming SDK release. I can probably provide a little more clarity then.

  • Anyone has a workaround for this code?

    var value = Properties.getValue(key);
    
    // this is what I would like to have, but doesn't compile
    if (value != null && value has :toNumber) {
        value = value.toNumber();
    }
    
    
    // but even this workaround doesn't work:
    if (value != null) {
        if (value has :toNumber) {
            value = value.toNumber();
        }
    }
    

    Cannot find symbol ':toNumber' on type '$.Toybox.Lang.Array<Null or $.Toybox.Application.PropertyKeyType or $.Toybox.Lang.Array<$.Toybox.Application.PropertyValueType> or $.Toybox.Lang.Dictionary<$.Toybox.Application.PropertyKeyType,$.Toybox.Application.PropertyValueType> or $.Toybox.WatchUi.BitmapResource>'.

  • I wouldn't use "has".  I'd use "instanceof"

    See the New Developer FAQ for an example

    https://forums.garmin.com/developer/connect-iq/w/wiki/4/new-developer-faq#settings-crash

  • except that that example doesn't compile with strict flag, and has even worse problems than my example Slight smile

    Cannot find symbol ':toNumber' on type '$.Toybox.Lang.Boolean'.
    Cannot find symbol ':toNumber' on type '$.Toybox.Lang.Dictionary<$.Toybox.Lang.Boolean or $.Toybox.Lang.Char or $.Toybox.Lang.Double or $.Toybox.Lang.Float or $.Toybox.Lang.Long or $.Toybox.Lang.Number or $.Toybox.Lang.String,Null or $.Toybox.Application.PropertyKeyType or $.Toybox.Lang.Array<$.Toybox.Application.PropertyValueType> or $.Toybox.Lang.Dictionary<$.Toybox.Application.PropertyKeyType,$.Toybox.Application.PropertyValueType> or $.Toybox.WatchUi.BitmapResource>'.
    Cannot find symbol ':toNumber' on type '$.Toybox.WatchUi.BitmapResource'.

  • Don't use strict.  I never do.

  • I know, you're the perfect programmer, but I'm not...

  • you don't need to use -l3.  You can use -l1 or -l2.  All I've seen about -l3 is that it's too strict and it will flag things in code that runs fine and likely will confuse more than it will help.

  • You can use (:typecheck(false)) to disable the type checker for a single function. So you could write

    (:typecheck(false))
    function toNumberIfPossible(value as Object?) as Number? {
      return value != null && value has :toNumber? value.toNumber() : null;
    }

    Note that although the type checker is disabled for this function, you can still type its argument, and return value, so that types continue to flow through the rest of the program.

    And of course, I wrote it using ?: rather than if/else, so that you can also say (:typecheck(false), :inline) :-)