This code
// @flow
type T = {
s? : string
}
function f(t:T) {
if (t.s == null){
return "";
}
if (t.s.indexOf("foo") != -1){
return "bar";
}
return t.s[0];
}
gives me this error
js/test.js:21
21: return t.s[0];
^^^^^^ access of computed property/element. Computed property/element cannot be accessed on possibly undefined value
21: return t.s[0];
^^^ undefined
If I replace condition with if (t.s.length < 2)
or leave only last return everything works great. Some other cases:
if (t.s.charCodeAt(0) != 13)
- bad
if (t.s.charAt(0) != 'a')
- bad
if (t.s.substr(0) != 'a')
- bad
if (t.s[0] != 'a')
- good
That's flow 0.34.0 on linux.
And if I remove T
completely, and make it function f(s?:string)
work fine also.
This is because calling functions (such as indexOf
) can potentially invalidate previous checks. Before you check some value you can assign it to local const
to avoid this.
Yeah, damned pessimistic calls. But why, especially for internal types? Anyway every property can be hidden by getter and/or Proxy, and trigger function call.
This seems one of the most misunderstood / frowned upon feature of Flow:
Just ran into this with .test
on regular expressions with:
opts.ignoreCustomPatterns.test(basename) || opts.ignoreCustomPatterns.test(path)
It seems silly that this is applied to builtin types, as they functionality should be guaranteed.
At least, the error message should indicate that this potential changing of value is the cause - as I just spent an hour thinking this was an issue with my type definitions, rather than with this crazyness.
This is because calling functions (such as indexOf) can potentially invalidate previous checks. Before you check some value you can assign it to local const to avoid this.
Yeah, I follow this and the flow stop giving this error.
Most helpful comment
This seems one of the most misunderstood / frowned upon feature of Flow: