Skip to content

Commit a2b4029

Browse files
authored
Merge pull request #31542 from andrewbranch/bug/31481
Error when writing to rest element range of readonly tuple
2 parents 5d9d4b2 + 9f6791a commit a2b4029

File tree

6 files changed

+147
-8
lines changed

6 files changed

+147
-8
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10106,6 +10106,7 @@ namespace ts {
1010610106
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
1010710107
}
1010810108
}
10109+
errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, IndexKind.Number));
1010910110
return mapType(objectType, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
1011010111
}
1011110112
}
@@ -10127,13 +10128,7 @@ namespace ts {
1012710128
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
1012810129
return indexInfo.type;
1012910130
}
10130-
if (indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
10131-
if (accessExpression) {
10132-
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
10133-
return indexInfo.type;
10134-
}
10135-
return undefined;
10136-
}
10131+
errorIfWritingToReadonlyIndex(indexInfo);
1013710132
return indexInfo.type;
1013810133
}
1013910134
if (indexType.flags & TypeFlags.Never) {
@@ -10193,6 +10188,12 @@ namespace ts {
1019310188
return indexType;
1019410189
}
1019510190
return undefined;
10191+
10192+
function errorIfWritingToReadonlyIndex(indexInfo: IndexInfo | undefined): void {
10193+
if (indexInfo && indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
10194+
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
10195+
}
10196+
}
1019610197
}
1019710198

1019810199
function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression) {

tests/baselines/reference/readonlyArraysAndTuples.errors.txt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS27
99
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(23,5): error TS4104: The type 'readonly [string, string]' is 'readonly' and cannot be assigned to the mutable type '[string, string]'.
1010
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(24,5): error TS2739: Type 'string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
1111
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
12+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(30,3): error TS2540: Cannot assign to '0' because it is a read-only property.
13+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(31,3): error TS2540: Cannot assign to '1' because it is a read-only property.
14+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(32,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
15+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(33,8): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
16+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(34,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
17+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(35,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
18+
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(36,8): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
1219

1320

14-
==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (11 errors) ====
21+
==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (18 errors) ====
1522
type T10 = string[];
1623
type T11 = Array<string>;
1724
type T12 = readonly string[];
@@ -61,4 +68,27 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS27
6168
!!! error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
6269
rt = mt;
6370
}
71+
72+
declare var v: readonly[number, number, ...number[]];
73+
v[0] = 1; // Error
74+
~
75+
!!! error TS2540: Cannot assign to '0' because it is a read-only property.
76+
v[1] = 1; // Error
77+
~
78+
!!! error TS2540: Cannot assign to '1' because it is a read-only property.
79+
v[2] = 1; // Error
80+
~~~~
81+
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
82+
delete v[2]; // Error
83+
~~~~
84+
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
85+
v[0 + 1] = 1; // Error
86+
~~~~~~~~
87+
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
88+
v[0 + 2] = 1; // Error
89+
~~~~~~~~
90+
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
91+
delete v[0 + 1]; // Error
92+
~~~~~~~~
93+
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
6494

tests/baselines/reference/readonlyArraysAndTuples.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,15 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
2626
rt = ra; // Error
2727
rt = mt;
2828
}
29+
30+
declare var v: readonly[number, number, ...number[]];
31+
v[0] = 1; // Error
32+
v[1] = 1; // Error
33+
v[2] = 1; // Error
34+
delete v[2]; // Error
35+
v[0 + 1] = 1; // Error
36+
v[0 + 2] = 1; // Error
37+
delete v[0 + 1]; // Error
2938

3039

3140
//// [readonlyArraysAndTuples.js]
@@ -44,6 +53,13 @@ function f1(ma, ra, mt, rt) {
4453
rt = ra; // Error
4554
rt = mt;
4655
}
56+
v[0] = 1; // Error
57+
v[1] = 1; // Error
58+
v[2] = 1; // Error
59+
delete v[2]; // Error
60+
v[0 + 1] = 1; // Error
61+
v[0 + 2] = 1; // Error
62+
delete v[0 + 1]; // Error
4763

4864

4965
//// [readonlyArraysAndTuples.d.ts]
@@ -58,3 +74,4 @@ declare type T31<T> = readonly T;
5874
declare type T32 = readonly readonly string[];
5975
declare type T33 = readonly Array<string>;
6076
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): void;
77+
declare var v: readonly [number, number, ...number[]];

tests/baselines/reference/readonlyArraysAndTuples.symbols

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,29 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
9090
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48))
9191
}
9292

93+
declare var v: readonly[number, number, ...number[]];
94+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
95+
96+
v[0] = 1; // Error
97+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
98+
>0 : Symbol(0)
99+
100+
v[1] = 1; // Error
101+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
102+
>1 : Symbol(1)
103+
104+
v[2] = 1; // Error
105+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
106+
107+
delete v[2]; // Error
108+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
109+
110+
v[0 + 1] = 1; // Error
111+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
112+
113+
v[0 + 2] = 1; // Error
114+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
115+
116+
delete v[0 + 1]; // Error
117+
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
118+

tests/baselines/reference/readonlyArraysAndTuples.types

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,59 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
9797
>mt : [string, string]
9898
}
9999

100+
declare var v: readonly[number, number, ...number[]];
101+
>v : readonly [number, number, ...number[]]
102+
103+
v[0] = 1; // Error
104+
>v[0] = 1 : 1
105+
>v[0] : any
106+
>v : readonly [number, number, ...number[]]
107+
>0 : 0
108+
>1 : 1
109+
110+
v[1] = 1; // Error
111+
>v[1] = 1 : 1
112+
>v[1] : any
113+
>v : readonly [number, number, ...number[]]
114+
>1 : 1
115+
>1 : 1
116+
117+
v[2] = 1; // Error
118+
>v[2] = 1 : 1
119+
>v[2] : number
120+
>v : readonly [number, number, ...number[]]
121+
>2 : 2
122+
>1 : 1
123+
124+
delete v[2]; // Error
125+
>delete v[2] : boolean
126+
>v[2] : number
127+
>v : readonly [number, number, ...number[]]
128+
>2 : 2
129+
130+
v[0 + 1] = 1; // Error
131+
>v[0 + 1] = 1 : 1
132+
>v[0 + 1] : number
133+
>v : readonly [number, number, ...number[]]
134+
>0 + 1 : number
135+
>0 : 0
136+
>1 : 1
137+
>1 : 1
138+
139+
v[0 + 2] = 1; // Error
140+
>v[0 + 2] = 1 : 1
141+
>v[0 + 2] : number
142+
>v : readonly [number, number, ...number[]]
143+
>0 + 2 : number
144+
>0 : 0
145+
>2 : 2
146+
>1 : 1
147+
148+
delete v[0 + 1]; // Error
149+
>delete v[0 + 1] : boolean
150+
>v[0 + 1] : number
151+
>v : readonly [number, number, ...number[]]
152+
>0 + 1 : number
153+
>0 : 0
154+
>1 : 1
155+

tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,12 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
2828
rt = ra; // Error
2929
rt = mt;
3030
}
31+
32+
declare var v: readonly[number, number, ...number[]];
33+
v[0] = 1; // Error
34+
v[1] = 1; // Error
35+
v[2] = 1; // Error
36+
delete v[2]; // Error
37+
v[0 + 1] = 1; // Error
38+
v[0 + 2] = 1; // Error
39+
delete v[0 + 1]; // Error

0 commit comments

Comments
 (0)