Skip to content

Commit

Permalink
Elaborate readonly array/tuple relation errors. Fixes microsoft#35060
Browse files Browse the repository at this point in the history
  • Loading branch information
Quincy Babin committed Nov 13, 2019
1 parent aa39080 commit c948d6f
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 1 deletion.
15 changes: 14 additions & 1 deletion src/compiler/checker.ts
Expand Up @@ -14537,6 +14537,13 @@ namespace ts {
if (isTupleLikeType(source)) {
const sourceTuple: TupleType | undefined = (source as TupleTypeReference).target;
if (sourceTuple && sourceTuple.readonly && isArrayOrTupleLikeType(target) &&
(isReadonlyArrayType(target) || isTupleType(target) && target.target.readonly)) {
if (reportErrors) {
reportError(Diagnostics.The_type_0_is_readonly_and_is_incompatible_with_type_1, typeToString(source), typeToString(target));
}
return false;
}
else if (sourceTuple && sourceTuple.readonly && isArrayOrTupleLikeType(target) &&
(!isReadonlyArrayType(target) || isTupleType(target) && !target.target.readonly)) {
if (reportErrors) {
reportError(Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
Expand All @@ -14554,6 +14561,12 @@ namespace ts {
}
return false;
}
if (isReadonlyArrayType(source) && isArrayType(target) && isReadonlyArrayType(target)) {
if (reportErrors) {
reportError(Diagnostics.The_type_0_is_readonly_and_is_incompatible_with_type_1, typeToString(source), typeToString(target));
}
return false;
}
return true;
}

Expand Down Expand Up @@ -36260,4 +36273,4 @@ namespace ts {
return !!(s.flags & SignatureFlags.HasLiteralTypes);
}

}
}
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Expand Up @@ -3148,6 +3148,10 @@
"category": "Error",
"code": 4110
},
"The type '{0}' is 'readonly' and is incompatible with type '{1}'.": {
"category": "Error",
"code": 4111
},

"The current host does not support the '{0}' option.": {
"category": "Error",
Expand Down
@@ -0,0 +1,21 @@
tests/cases/compiler/readOnlyArrayAndTuplesAssignmentElaboration.ts(4,7): error TS4111: The type 'readonly [0]' is 'readonly' and is incompatible with type 'readonly []'.
Types of property 'length' are incompatible.
Type '1' is not assignable to type '0'.
tests/cases/compiler/readOnlyArrayAndTuplesAssignmentElaboration.ts(5,7): error TS4111: The type 'readonly [0]' is 'readonly' and is incompatible with type 'readonly [1]'.
Type '0' is not assignable to type '1'.


==== tests/cases/compiler/readOnlyArrayAndTuplesAssignmentElaboration.ts (2 errors) ====
// @strict
// #Repro from #35060

const x: readonly [] = null! as readonly [0];
~
!!! error TS4111: The type 'readonly [0]' is 'readonly' and is incompatible with type 'readonly []'.
!!! error TS4111: Types of property 'length' are incompatible.
!!! error TS4111: Type '1' is not assignable to type '0'.
const y: readonly [1] = null! as readonly [0];
~
!!! error TS4111: The type 'readonly [0]' is 'readonly' and is incompatible with type 'readonly [1]'.
!!! error TS4111: Type '0' is not assignable to type '1'.

@@ -0,0 +1,13 @@
//// [readOnlyArrayAndTuplesAssignmentElaboration.ts]
// @strict
// #Repro from #35060

const x: readonly [] = null! as readonly [0];
const y: readonly [1] = null! as readonly [0];


//// [readOnlyArrayAndTuplesAssignmentElaboration.js]
// @strict
// #Repro from #35060
var x = null;
var y = null;
@@ -0,0 +1,10 @@
=== tests/cases/compiler/readOnlyArrayAndTuplesAssignmentElaboration.ts ===
// @strict
// #Repro from #35060

const x: readonly [] = null! as readonly [0];
>x : Symbol(x, Decl(readOnlyArrayAndTuplesAssignmentElaboration.ts, 3, 5))

const y: readonly [1] = null! as readonly [0];
>y : Symbol(y, Decl(readOnlyArrayAndTuplesAssignmentElaboration.ts, 4, 5))

@@ -0,0 +1,16 @@
=== tests/cases/compiler/readOnlyArrayAndTuplesAssignmentElaboration.ts ===
// @strict
// #Repro from #35060

const x: readonly [] = null! as readonly [0];
>x : readonly []
>null! as readonly [0] : readonly [0]
>null! : null
>null : null

const y: readonly [1] = null! as readonly [0];
>y : readonly [1]
>null! as readonly [0] : readonly [0]
>null! : null
>null : null

@@ -0,0 +1,5 @@
// @strict
// #Repro from #35060

const x: readonly [] = null! as readonly [0];
const y: readonly [1] = null! as readonly [0];

0 comments on commit c948d6f

Please sign in to comment.