TypeScript: Object is possibly undefined` error in TypeScript 4.1.2
TypeScript Version: 4.1.2
Search Terms: Object is possibly undefined
Code
function main(values: Array<string>) {
for (let i = 0; i < values.length; i++) {
if (typeof values[i] === 'string' && values[i].length > 0) {
console.log(i);
}
}
}
Expected behavior: No error
Actual behavior:
TypeScript 4.1.2 reports a Object is possibly undefined error in values[i].length but given the first condition the object must be defined as it is of type ‘string’
Related Issues: no
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 22 (8 by maintainers)
@RyanCavanaugh this should work as well
since
ReadonlyArraycan’t magically change what indexes are in the set and what are notThis was one of the caveats that kept the flag from being implemented for so long. We don’t have any way to ascertain whether
ior the indexed array has changed between any two arbitrary expressions, so the only “safe” thing to do is always includeundefined. You can write@radekmie
barin this case” so I just want to focus on this caseI appreciate having that option, but it mixes together two different concerns in an inseparable way
I think there is a good chunk of people that would like having option 2 without also being forced into option 1 (as it is much more rare, while 2. is very common).
Even so, it is a valuable improvement, just not as useful as it could be.
This isn’t true. A
ReadonlyArraymight be an alias for an underlying mutable array. e.g.@yume-chan I just wanted to emphasize that being
const-constant is not enough, that’s all. I agree with 3 though.@peterholak Option two would require a way to represent immutable types in TypeScript. This is currently not possible. It’s something I personally really want, but it’s nothing in the foreseeable future. Issues to follow would be #14909, #16317, #17181.
I know TS doesn’t recognize this pattern, even for normal optional properties:
(Playground link)
However I can’t understand why:
If it’s because a variable (
barin this case) may change between two accesses, sincebaris a constant, it’s not possible.If you say the object (
fooin this case) may change, then why does accessing with literals work? I expect they (access with literals and variables) both work or not work, and I prefer both not.The entire point of the flag was to be more safe than TS’s normal behavior, so it being more restrictive than the default is a not undesirable aspect.
@doberkofler Consider the following (contrived) example though
values[i].length is no longer guaranteed to be defined, and TS has no good way to detecting that change.
@doberkofler sorry for confusion. it should but it does not.
https://www.typescriptlang.org/play?noUncheckedIndexedAccess=true&ts=4.1.0-beta&ssl=1&ssc=31&pln=1&pc=23#code/GYVwdgxgLglg9mABAWwIYzACgG6oDYgCmAzgFyIBKhqAJgngJ4CCATi6gwDzFQsYDmAPgCUiAN4AoRNMTA4LRJjyEoiGIgC8iAAwBuNYk6JcBEgDplYflAAW+mAGoHoyTLdrgiqAwAOhOJ4mRMQA2jAAupoaWgDkPHxWMYgAZMnG+MFh4RaEVraIgjouUu6lEAjEcMoWcPyYMMK6JaUAvs2IbS1AA
@thecotne Just to make sure: it should but it does not. Correct?