Uh oh!
There was an error while loading. Please reload this page.
A second attempt at readonly array support persisting through isArray - #42316
A second attempt at readonly array support persisting through isArray#42316Orta Therox (orta) wants to merge 1 commit into
Conversation
Orta Therox (orta)
commented
Jan 13, 2021
TypeScript Bot (@typescript-bot) pack this |
Heya Orta Therox (@orta), I've started to run the tarball bundle task on this PR at 289b0c8. You can monitor the build here. |
74341a0 to
f6b438bComparef6b438b to
6cd8141Compare| v // Validator & Partial<OnChanges> via subtype reduction | ||
| if (v.onChanges) { | ||
| ~~~~~~~~~ | ||
| !!! error TS2339: Property 'onChanges' does not exist on type 'C | (Validator & Partial<OnChanges>)'. |
There was a problem hiding this comment.
this looks like a regression. I reported this case back then, because the effect of instaceof affected code outside of the if statement
| <T>(arrayLength: number): T[]; | ||
| <T>(...items: T[]): T[]; | ||
| isArray(arg: any): arg is any[]; | ||
| isArray(arg: any): arg is readonly unknown[]; |
There was a problem hiding this comment.
This is a safer type, but it can't help but break anybody who was previously able to mutate an array or use its contents after checking it with isArray. I think it's too breaky for the benefit.
There was a problem hiding this comment.
Nathan Shively-Sanders (@sandersn) You mean anybody who was previously able to mutate a mutable array after checking it with isArray? I tested this change locally and confirmed it doesn't break that: Mutable arrays remain mutable. The type predicate narrows the type to the intersection of typeof arg & readonly unknown[], which is only immutable if arg was already immutable.
Would you consider reopening this PR?
⏯️ Playground link
🧑💻 Code
declareconstmutable: string[];declareconstimmutable: readonlystring[];// Mutable arrays remain so with and without// https://github.com/microsoft/TypeScript/pull/42316if(Array.isArray(mutable)){constshould: string[]=mutable;// ✔️ A mutable array should remain so}// This assignment should error but doesn't, not without// https://github.com/microsoft/TypeScript/pull/42316if(Array.isArray(immutable)){constshouldNot: string[]=immutable;// ❌ An immutable array should remain so}🙁 Actual behavior
$ tsc input.tsNo errors: You're free to mutate an immutable array.
🙂 Expected behavior
With this PR:
$ node built/local/tsc.js input.ts input.ts:13:9 - error TS4104: The type'readonly string[]' is 'readonly' and cannot be assigned to the mutable type'string[]'.
13 const shouldNot: string[] = immutable; // ❌ An immutable array should remain so
~~~~~~~~~
Found 1 error in input.ts:13Mutating an immutable array is an error.
There was a problem hiding this comment.
What I mean is that if somebody writes this today, it's not an error:
declareconstu: unknown;if(Array.isArray(u)){u[1]=12u[1].length}unknown narrowing is an important scenario for Array.isArray, and this change would add errors that were not there before and are not necessarily correct.
There was a problem hiding this comment.
Nathan Shively-Sanders (@sandersn) I should've realized what you meant, thanks for your patience.
Instead of replacing the existing signature, would adding overloads for ArrayLike<T> and Iterable<T> work, without affecting the current behavior of any and unknown? I've opened #48228 with that modification to this PR.
A different attempt at #39258 which persists
readonlythroughisArrayfound during some investigations for #42231 without the complications of breaking generics etc.