Skip to content
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

Error when writing to rest element range of readonly tuple #31542

Merged
merged 2 commits into from May 23, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
15 changes: 8 additions & 7 deletions src/compiler/checker.ts
Expand Up @@ -10101,6 +10101,7 @@ namespace ts {
error(indexNode, Diagnostics.Property_0_does_not_exist_on_type_1, unescapeLeadingUnderscores(propName), typeToString(objectType));
}
}
errorIfWritingToReadonlyIndex(getIndexInfoOfType(objectType, IndexKind.Number));
return mapType(objectType, t => getRestTypeOfTupleType(<TupleTypeReference>t) || undefinedType);
}
}
Expand All @@ -10122,13 +10123,7 @@ namespace ts {
error(indexNode, Diagnostics.Type_0_cannot_be_used_as_an_index_type, typeToString(indexType));
return indexInfo.type;
}
if (indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
if (accessExpression) {
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
return indexInfo.type;
}
return undefined;
}
errorIfWritingToReadonlyIndex(indexInfo);
return indexInfo.type;
}
if (indexType.flags & TypeFlags.Never) {
Expand Down Expand Up @@ -10188,6 +10183,12 @@ namespace ts {
return indexType;
}
return undefined;

function errorIfWritingToReadonlyIndex(indexInfo: IndexInfo | undefined): void {
if (indexInfo && indexInfo.isReadonly && accessExpression && (isAssignmentTarget(accessExpression) || isDeleteTarget(accessExpression))) {
error(accessExpression, Diagnostics.Index_signature_in_type_0_only_permits_reading, typeToString(objectType));
}
}
}

function getIndexNodeForAccessExpression(accessNode: ElementAccessExpression | IndexedAccessTypeNode | PropertyName | BindingName | SyntheticExpression) {
Expand Down
32 changes: 31 additions & 1 deletion tests/baselines/reference/readonlyArraysAndTuples.errors.txt
Expand Up @@ -9,9 +9,16 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(22,5): error TS27
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]'.
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
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
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(30,3): error TS2540: Cannot assign to '0' because it is a read-only property.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(31,3): error TS2540: Cannot assign to '1' because it is a read-only property.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(32,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(33,8): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(34,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(35,1): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(36,8): error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.


==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (11 errors) ====
==== tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts (18 errors) ====
type T10 = string[];
type T11 = Array<string>;
type T12 = readonly string[];
Expand Down Expand Up @@ -61,4 +68,27 @@ tests/cases/conformance/types/tuple/readonlyArraysAndTuples.ts(25,5): error TS27
!!! error TS2739: Type 'readonly string[]' is missing the following properties from type 'readonly [string, string]': 0, 1
rt = mt;
}

declare var v: readonly[number, number, ...number[]];
v[0] = 1; // Error
~
!!! error TS2540: Cannot assign to '0' because it is a read-only property.
v[1] = 1; // Error
~
!!! error TS2540: Cannot assign to '1' because it is a read-only property.
v[2] = 1; // Error
~~~~
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
delete v[2]; // Error
~~~~
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
v[0 + 1] = 1; // Error
~~~~~~~~
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
v[0 + 2] = 1; // Error
~~~~~~~~
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.
delete v[0 + 1]; // Error
~~~~~~~~
!!! error TS2542: Index signature in type 'readonly [number, number, ...number[]]' only permits reading.

17 changes: 17 additions & 0 deletions tests/baselines/reference/readonlyArraysAndTuples.js
Expand Up @@ -26,6 +26,15 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
rt = ra; // Error
rt = mt;
}

declare var v: readonly[number, number, ...number[]];
v[0] = 1; // Error
v[1] = 1; // Error
v[2] = 1; // Error
delete v[2]; // Error
v[0 + 1] = 1; // Error
v[0 + 2] = 1; // Error
delete v[0 + 1]; // Error


//// [readonlyArraysAndTuples.js]
Expand All @@ -44,6 +53,13 @@ function f1(ma, ra, mt, rt) {
rt = ra; // Error
rt = mt;
}
v[0] = 1; // Error
v[1] = 1; // Error
v[2] = 1; // Error
delete v[2]; // Error
v[0 + 1] = 1; // Error
v[0 + 2] = 1; // Error
delete v[0 + 1]; // Error


//// [readonlyArraysAndTuples.d.ts]
Expand All @@ -58,3 +74,4 @@ declare type T31<T> = readonly T;
declare type T32 = readonly readonly string[];
declare type T33 = readonly Array<string>;
declare function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: readonly [string, string]): void;
declare var v: readonly [number, number, ...number[]];
26 changes: 26 additions & 0 deletions tests/baselines/reference/readonlyArraysAndTuples.symbols
Expand Up @@ -90,3 +90,29 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
>mt : Symbol(mt, Decl(readonlyArraysAndTuples.ts, 13, 48))
}

declare var v: readonly[number, number, ...number[]];
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

v[0] = 1; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
>0 : Symbol(0)

v[1] = 1; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))
>1 : Symbol(1)

v[2] = 1; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

delete v[2]; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

v[0 + 1] = 1; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

v[0 + 2] = 1; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

delete v[0 + 1]; // Error
>v : Symbol(v, Decl(readonlyArraysAndTuples.ts, 28, 11))

56 changes: 56 additions & 0 deletions tests/baselines/reference/readonlyArraysAndTuples.types
Expand Up @@ -97,3 +97,59 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
>mt : [string, string]
}

declare var v: readonly[number, number, ...number[]];
>v : readonly [number, number, ...number[]]

v[0] = 1; // Error
>v[0] = 1 : 1
>v[0] : any
>v : readonly [number, number, ...number[]]
>0 : 0
>1 : 1

v[1] = 1; // Error
>v[1] = 1 : 1
>v[1] : any
>v : readonly [number, number, ...number[]]
>1 : 1
>1 : 1

v[2] = 1; // Error
>v[2] = 1 : 1
>v[2] : number
>v : readonly [number, number, ...number[]]
>2 : 2
>1 : 1

delete v[2]; // Error
>delete v[2] : boolean
>v[2] : number
>v : readonly [number, number, ...number[]]
>2 : 2

v[0 + 1] = 1; // Error
>v[0 + 1] = 1 : 1
>v[0 + 1] : number
>v : readonly [number, number, ...number[]]
>0 + 1 : number
>0 : 0
>1 : 1
>1 : 1

v[0 + 2] = 1; // Error
>v[0 + 2] = 1 : 1
>v[0 + 2] : number
>v : readonly [number, number, ...number[]]
>0 + 2 : number
>0 : 0
>2 : 2
>1 : 1

delete v[0 + 1]; // Error
>delete v[0 + 1] : boolean
>v[0 + 1] : number
>v : readonly [number, number, ...number[]]
>0 + 1 : number
>0 : 0
>1 : 1

Expand Up @@ -28,3 +28,12 @@ function f1(ma: string[], ra: readonly string[], mt: [string, string], rt: reado
rt = ra; // Error
rt = mt;
}

declare var v: readonly[number, number, ...number[]];
v[0] = 1; // Error
v[1] = 1; // Error
v[2] = 1; // Error
delete v[2]; // Error
v[0 + 1] = 1; // Error
v[0 + 2] = 1; // Error
delete v[0 + 1]; // Error