Consistently error when rest element isn't last in tuple type (#40254)

* Consistently error when rest element isn't last in tuple type

* Add regression test

* Accept new baselines

* Stricter circular recursion check in type inference

* Revert "Stricter circular recursion check in type inference"

This reverts commit 80e6df6230.

* Revert "Accept new baselines"

This reverts commit 355706dadc.

* Accept new baselines
This commit is contained in:
Anders Hejlsberg
2020-09-08 07:14:16 -10:00
committed by GitHub
parent de5ef356b6
commit cea1cfb82e
6 changed files with 105 additions and 6 deletions

View File

@@ -31172,6 +31172,7 @@ namespace ts {
function checkTupleType(node: TupleTypeNode) {
const elementTypes = node.elements;
let seenOptionalElement = false;
let seenRestElement = false;
const hasNamedElement = some(elementTypes, isNamedTupleMember);
for (let i = 0; i < elementTypes.length; i++) {
const e = elementTypes[i];
@@ -31181,16 +31182,17 @@ namespace ts {
}
const flags = getTupleElementFlags(e);
if (flags & ElementFlags.Variadic) {
if (!isArrayLikeType(getTypeFromTypeNode((<RestTypeNode | NamedTupleMember>e).type))) {
const type = getTypeFromTypeNode((<RestTypeNode | NamedTupleMember>e).type);
if (!isArrayLikeType(type)) {
error(e, Diagnostics.A_rest_element_type_must_be_an_array_type);
break;
}
if (isArrayType(type) || isTupleType(type) && type.target.combinedFlags & ElementFlags.Rest) {
seenRestElement = true;
}
}
else if (flags & ElementFlags.Rest) {
if (i !== elementTypes.length - 1) {
grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
break;
}
seenRestElement = true;
}
else if (flags & ElementFlags.Optional) {
seenOptionalElement = true;
@@ -31199,6 +31201,10 @@ namespace ts {
grammarErrorOnNode(e, Diagnostics.A_required_element_cannot_follow_an_optional_element);
break;
}
if (seenRestElement && i !== elementTypes.length - 1) {
grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
break;
}
}
forEach(node.elements, checkSourceElement);
}