Elaborate array and tuple relation errors

This commit is contained in:
Jack Williams
2019-04-13 17:29:40 +01:00
parent 4fee628447
commit 2ea91a0e9c
12 changed files with 322 additions and 23 deletions

View File

@@ -12246,6 +12246,40 @@ namespace ts {
}
}
/**
* Try and elaborate array and tuple errors. Returns false
* if we have found an elaboration, or we should ignore
* any other elaborations when relating the `source` and
* `target` types.
*
* @param source
* @param target
* @param reportErrors
*/
function tryElaborateArrayLikeErrors(source: Type, target: Type, reportErrors: boolean): boolean {
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_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
}
return false;
}
return isArrayLikeType(target);
}
if (isTupleLikeType(target)) {
return isArrayLikeType(source);
}
if (isReadonlyArrayType(source) && isArrayType(target) && !isReadonlyArrayType(target)) {
if (reportErrors) {
reportError(Diagnostics.The_type_0_is_readonly_and_cannot_be_assigned_to_the_mutable_type_1, typeToString(source), typeToString(target));
}
return false;
}
return true;
}
function isUnionOrIntersectionTypeWithoutNullableConstituents(type: Type): boolean {
if (!(type.flags & TypeFlags.UnionOrIntersection)) {
return false;
@@ -12418,6 +12452,9 @@ namespace ts {
if (!result && reportErrors) {
const maybeSuppress = suppressNextError;
suppressNextError = false;
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Object) {
tryElaborateArrayLikeErrors(source, target, reportErrors);
}
if (source.flags & TypeFlags.Object && target.flags & TypeFlags.Primitive) {
tryElaborateErrorsForPrimitivesAndObjects(source, target);
}
@@ -13148,11 +13185,13 @@ namespace ts {
associateRelatedInfo(createDiagnosticForNode(unmatchedProperty.declarations[0], Diagnostics._0_is_declared_here, propName));
}
}
else if (props.length > 5) { // arbitrary cutoff for too-long list form
reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4);
}
else {
reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", "));
else if (tryElaborateArrayLikeErrors(source, target, /*reportErrors*/ false)) {
if (props.length > 5) { // arbitrary cutoff for too-long list form
reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2_and_3_more, typeToString(source), typeToString(target), map(props.slice(0, 4), p => symbolToString(p)).join(", "), props.length - 4);
}
else {
reportError(Diagnostics.Type_0_is_missing_the_following_properties_from_type_1_Colon_2, typeToString(source), typeToString(target), map(props, p => symbolToString(p)).join(", "));
}
}
}
return Ternary.False;

View File

@@ -2943,7 +2943,11 @@
"category": "Error",
"code": 4103
},
"The type '{0}' is 'readonly' and cannot be assigned to the mutable type '{1}'.": {
"category": "Error",
"code": 4104
},
"The current host does not support the '{0}' option.": {
"category": "Error",
"code": 5001