-
Notifications
You must be signed in to change notification settings - Fork 12.8k
A length>0 on a readonly array should guarantee destructured element is known, not undefined #42909
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weβll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
function unshiftOrNothing(items:number[]) : number{
if(items.length > 0){
console.log("the result of clearing the array was " + clearItemsArray());
const [unshifted, ...rest] = items;
return unshifted;
}
return 0;
} We don't intend to special-case the exact form of there being no in-between code between the length check and the destructuring. |
I didn't make clear that for the typical immutable case, flagging it Nevertheless with indexed access checks, the compiler considers that the readonly array below could potentially be empty after a >0 zero length check. Would welcome other workarounds or ways to nudge the compiler but I haven't found any which have an effect other than casting (potentially unsafe if I missed some case - as you drew attention to).
|
Readonly is not immutability. You can have a readonly view of an array which is itself mutable. |
Thanks, Ryan! I had misunderstood how the readonly marking was managed. I misinterpreted compilation errors I've encountered before around readonly. You've taught me an array which typescript treats as read/write in one context could become readonly within a different one without bypassing typescript. I knew these are just javascript arrays and obviously mutable under the hood but hadn't recognised the situations where writing was possible actually from within typescript. Thought readonly arrays which had no other references, or which had arrived with the flag already were the only ones the compiler would accept as readonly, making them 'compile-time safe'. This was a mistake. For example in this code sample I thought adding the
Thanks for taking the time to fill me in. |
Why? See microsoft/TypeScript#42909.
Suggestion
π Search Terms
Array Destructuring, noUncheckedIndexedAccess, length check
β Viability Checklist
My suggestion meets these guidelines:
β Suggestion
A length check with length more than zero should eliminate
undefined
from possible values when destructuring.Looking at the example below, it's impossible that destructuring
[unshifted,...rest]
from the array could lead tounshifted
being undefined, since the length is checked first. Nevertheless when noUncheckedIndexedAccess is set in Tsconfig, it treatsundefined
as a possible path.π Motivating Example
I have encountered this a lot when manipulating 'immutable' arrays e.g. for queues or redux state which require the use of destructuring, since array methods change the array.
I can't identify a type-safe alternative or check which ensures that the typescript compiler picks up on the fact the first item must be set.
π» Use Cases
A workaround is to lie to the compiler that items is a tuple containing at least one item. However, I don't know what knock-on effect that has on e.g. type guarantees about
...rest
- it's presumably expected to be a zero-length tuple which might break other things.The text was updated successfully, but these errors were encountered: