Skip to content

Commit 83a873d

Browse files
committed
Consistently error when rest element isn't last in tuple type
1 parent c5446d1 commit 83a873d

File tree

1 file changed

+11
-5
lines changed

1 file changed

+11
-5
lines changed

src/compiler/checker.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31121,6 +31121,7 @@ namespace ts {
3112131121
function checkTupleType(node: TupleTypeNode) {
3112231122
const elementTypes = node.elements;
3112331123
let seenOptionalElement = false;
31124+
let seenRestElement = false;
3112431125
const hasNamedElement = some(elementTypes, isNamedTupleMember);
3112531126
for (let i = 0; i < elementTypes.length; i++) {
3112631127
const e = elementTypes[i];
@@ -31130,16 +31131,17 @@ namespace ts {
3113031131
}
3113131132
const flags = getTupleElementFlags(e);
3113231133
if (flags & ElementFlags.Variadic) {
31133-
if (!isArrayLikeType(getTypeFromTypeNode((<RestTypeNode | NamedTupleMember>e).type))) {
31134+
const type = getTypeFromTypeNode((<RestTypeNode | NamedTupleMember>e).type);
31135+
if (!isArrayLikeType(type)) {
3113431136
error(e, Diagnostics.A_rest_element_type_must_be_an_array_type);
3113531137
break;
3113631138
}
31139+
if (isArrayType(type) || isTupleType(type) && type.target.combinedFlags & ElementFlags.Rest) {
31140+
seenRestElement = true;
31141+
}
3113731142
}
3113831143
else if (flags & ElementFlags.Rest) {
31139-
if (i !== elementTypes.length - 1) {
31140-
grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
31141-
break;
31142-
}
31144+
seenRestElement = true;
3114331145
}
3114431146
else if (flags & ElementFlags.Optional) {
3114531147
seenOptionalElement = true;
@@ -31148,6 +31150,10 @@ namespace ts {
3114831150
grammarErrorOnNode(e, Diagnostics.A_required_element_cannot_follow_an_optional_element);
3114931151
break;
3115031152
}
31153+
if (seenRestElement && i !== elementTypes.length - 1) {
31154+
grammarErrorOnNode(e, Diagnostics.A_rest_element_must_be_last_in_a_tuple_type);
31155+
break;
31156+
}
3115131157
}
3115231158
forEach(node.elements, checkSourceElement);
3115331159
}

0 commit comments

Comments
 (0)