From fa2ffe2dd16871a893701b7771df729156d9d6f7 Mon Sep 17 00:00:00 2001 From: Sysix <3897725+Sysix@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:40:19 +0000 Subject: [PATCH] feat(parser): add ts error 1266 for `TSTupleElement` (#18145) --- crates/oxc_parser/src/diagnostics.rs | 9 +++++++++ crates/oxc_parser/src/ts/types.rs | 9 +++++++++ tasks/coverage/snapshots/parser_typescript.snap | 10 ++++++++++ 3 files changed, 28 insertions(+) diff --git a/crates/oxc_parser/src/diagnostics.rs b/crates/oxc_parser/src/diagnostics.rs index 0fd7e7c786f43..c4844405e73cd 100644 --- a/crates/oxc_parser/src/diagnostics.rs +++ b/crates/oxc_parser/src/diagnostics.rs @@ -353,6 +353,15 @@ pub fn rest_element_cannot_follow_another_rest_element( .with_labels([span.label("Second rest element here"), seen_span.label("First seen here")]) } +/// An optional element cannot follow a rest element. ts(1266) +#[cold] +pub fn optional_element_cannot_follow_rest_element(span: Span, rest_span: Span) -> OxcDiagnostic { + ts_error("1266", "An optional element cannot follow a rest element.").with_labels([ + span.label("Optional element here"), + rest_span.label("Rest element seen here"), + ]) +} + // A type-only import can specify a default import or named bindings, but not both. ts(1363) #[cold] pub fn type_only_import_default_and_named(specifier_span: Span) -> OxcDiagnostic { diff --git a/crates/oxc_parser/src/ts/types.rs b/crates/oxc_parser/src/ts/types.rs index a3faee59cf185..37cb6b05aca3b 100644 --- a/crates/oxc_parser/src/ts/types.rs +++ b/crates/oxc_parser/src/ts/types.rs @@ -926,6 +926,15 @@ impl<'a> ParserImpl<'a> { } seen_type_span = Some(tuple.span()); } + + if let Some(seen_rest_span) = seen_type_span + && matches!(tuple, TSTupleElement::TSOptionalType(_)) + { + me.error(diagnostics::optional_element_cannot_follow_rest_element( + tuple.span(), + seen_rest_span, + )); + } tuple }); self.expect(Kind::RBrack); diff --git a/tasks/coverage/snapshots/parser_typescript.snap b/tasks/coverage/snapshots/parser_typescript.snap index d03b7576b2fc7..ad5de38b74bce 100644 --- a/tasks/coverage/snapshots/parser_typescript.snap +++ b/tasks/coverage/snapshots/parser_typescript.snap @@ -26514,6 +26514,16 @@ Expect to Parse: tasks/coverage/typescript/tests/cases/conformance/statements/Va 8 │ type V11 = [number, ...string[], boolean?]; // Error ╰──── + × TS(1266): An optional element cannot follow a rest element. + ╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:8:21] + 7 │ type V10 = [number, ...string[], ...boolean[]]; // Error + 8 │ type V11 = [number, ...string[], boolean?]; // Error + · ─────┬───── ────┬─── + · │ ╰── Optional element here + · ╰── Rest element seen here + 9 │ type V12 = [number, string?, boolean]; // Error + ╰──── + × TS(1265): A rest element cannot follow another rest element. ╭─[typescript/tests/cases/conformance/types/tuple/variadicTuples2.ts:11:13] 10 │