Monkey type checking on resources


I keep getting warnings (typcheck set to 'informative') about Monkey types for resources. For example, "Cannot find symbol ':toFloat' on type '$.Toybox.WatchUi.BitmapResource'". I am making sure in my resources that the entered value must be numeric via settingConfig type="numeric" but the compiler still gives me a warning for Bitmaps, Booleans, Chars, etc.. How to avoid this?

Top Replies

All Replies

  • What exactly would be a float representation of a bitmap????? You can't convert a bitmap to a float.

  • I think OP is trying to say that they're trying to load a non-bitmap resource, but the typechecker is giving them a warning because they're using loadResource() without a type cast (loadResource() returns a String or Dictionary or BitmapResource or ...). Calling toFloat() on the loaded resource would lead to a type warning / error even if the resource is a string, because the type checker doesn't know it's a string (it thinks it could be any of the possible resource types).

    (Unfortunately, the type checker can't infer the type of a resource or property even if the dev can.)

    However, I'm confused about something:

      I am making sure in my resources that the entered value must be numeric via settingConfig type="numeric" 

    - resources and settings are 2 different things. Settings are associated with properties, not resources. It's not possible to have a numeric setting which is tied to a resource as far as I know.

    - resources can't be a Number, Boolean or Char. The full list of resource types returned by Application.loadResource() is:

    Lang.Array or Lang.Dictionary or Lang.String or WatchUi.AnimationResource or WatchUi.BitmapResource or WatchUi.FontResource (or Graphics.BitmapReference or Graphics.FontReference)

    @9321273, are you calling Application.Properties.getValue() / AppBase.getProperty() or Application.loadResource() / WatchUi.loadResource()?

    Either way the solution is a type cast (which imo is always a tool of last resort, but in this case it's necessary if you want to get rid of the warning.)

    e.g.

    var x = Application.loadResource(Rez.Strings.foo) as String;
    var y = x.toFloat();

    or

    var x = Application.Properties.getValue("foo") as String;
    var y = x.toFloat();

  • Indeed, the float setting was done in the "resources->properties" while in the "resources->settings->settingConfig" the type was numeric. I am loading the settings with Application.Properties.getValue(...) and I have now typecast them. The only thing I need to perhaps worry about is whether the user can set these to "null" by accident.

  • I now encountered a similar problem with type checking even when I verify the type according to the manual/documentation: I have the code: ```if (info.currentPower instanceof Number) {foo.add(info.currentPower);}``` where foo is an array of numbers. Again the type checker complaints and I need to typecast after having just checked the type (I also check that the property exists). Am I supposed to code ```if (info.currentPower instanceof Number) {foo.add(info.currentPower as Number);}```?

  • I now encountered a similar problem with type checking even when I verify the type according to the manual/documentation: I have the code: ```if (info.currentPower instanceof Number) {foo.add(info.currentPower);}``` where foo is an array of numbers. Again the type checker complaints and I need to typecast after having just checked the type (I also check that the property exists). Am I supposed to code ```if (info.currentPower instanceof Number) {foo.add(info.currentPower as Number);}```?

    Due to a quirk in the type checker, type narrowing (as above) doesn't seem to work on members of other objects (it does seem to work on local variables and member variables of the currently scoped object.) For the same reason, it won't help to type "if (info.currentPower != null)"

    The workaround is to assign info.currentPower to a local variable first. e.g.

    var currentPower = info.currentPower;
    if (currentPower != null) {
        foo.add(currentPower);
    }
    // or 
    if (currentPower instanceof Number) {
        foo.add(currentPower);
    }
    

    (Also, I wish this forum supported markdown too T_T. Additionally, both Insert > Code and the inline Code format have problems....)

  • The only thing I need to perhaps worry about is whether the user can set these to "null" by accident.

    There has definitely been an edge case years ago where all properties could come back as null, and it's *possible* people have seen something similar today.

    When I encountered this years ago, I ended implementing a null check for properties, and I also had to reimplement property defaults in code (because my app still had to use *some* values when when nulls were received.) (This sucked bc default values had to be hardcoded in 2 places - resources and code - but there was no way around it.)

  • Ahh, now I see. One has to click "Insert Code" to get the nice code layout you are using!