ezno_parser/types/
type_annotations.rs

1use std::ops::Neg;
2
3use crate::ast::VariableOrPropertyAccess;
4use crate::{
5	derive_ASTNode, parse_bracketed, throw_unexpected_token_with_token, to_string_bracketed,
6	ListItem, ParseErrors, Quoted,
7};
8use crate::{
9	errors::parse_lexing_error, extensions::decorators::Decorated, Decorator, Marker, ParseResult,
10	VariableField, WithComment,
11};
12use derive_partial_eq_extras::PartialEqExtras;
13use iterator_endiate::EndiateIteratorExt;
14use tokenizer_lib::sized_tokens::{SizedToken, TokenEnd, TokenReaderWithTokenEnds, TokenStart};
15
16use super::{
17	interface::{parse_interface_members, InterfaceMember},
18	type_declarations::TypeParameter,
19};
20
21use crate::{
22	number::NumberRepresentation, tokens::token_as_identifier, ASTNode, ParseError, ParseOptions,
23	Span, TSXKeyword, TSXToken, Token, TokenReader,
24};
25
26/// A reference to a type
27#[apply(derive_ASTNode)]
28#[derive(Debug, Clone, PartialEqExtras, get_field_by_type::GetFieldByType)]
29#[get_field_by_type_target(Span)]
30#[partial_eq_ignore_types(Span)]
31pub enum TypeAnnotation {
32	/// Common types that don't have to allocate a string for
33	CommonName(CommonTypes, Span),
34	/// A name e.g. `IPost`
35	Name(TypeName, Span),
36	/// A name with generics e.g. `Array<number>`
37	NameWithGenericArguments(TypeName, Vec<TypeAnnotation>, Span),
38	/// Union e.g. `number | string`
39	Union(Vec<TypeAnnotation>, Span),
40	/// Intersection e.g. `c & d`
41	Intersection(Vec<TypeAnnotation>, Span),
42	/// String literal e.g. `"foo"`
43	StringLiteral(String, Quoted, Span),
44	/// Number literal e.g. `45`
45	NumberLiteral(NumberRepresentation, Span),
46	/// Boolean literal e.g. `true`
47	BooleanLiteral(bool, Span),
48	/// Array literal e.g. `string[]`. This is syntactic sugar for `Array` with type arguments. **This is not the same
49	/// as a [TypeAnnotation::TupleLiteral]**
50	ArrayLiteral(Box<TypeAnnotation>, Span),
51	/// Function literal e.g. `(x: string) => string`
52	FunctionLiteral {
53		type_parameters: Option<Vec<TypeParameter>>,
54		parameters: TypeAnnotationFunctionParameters,
55		return_type: Box<TypeAnnotation>,
56		position: Span,
57	},
58	/// Construction literal e.g. `new (x: string) => string`
59	ConstructorLiteral {
60		type_parameters: Option<Vec<TypeParameter>>,
61		parameters: TypeAnnotationFunctionParameters,
62		return_type: Box<TypeAnnotation>,
63		position: Span,
64	},
65	/// Object literal e.g. `{ y: string }`
66	ObjectLiteral(Vec<WithComment<Decorated<InterfaceMember>>>, Span),
67	/// Tuple literal e.g. `[number, x: string]`
68	TupleLiteral(Vec<TupleLiteralElement>, Span),
69	/// ?
70	TemplateLiteral {
71		parts: Vec<(String, AnnotationWithBinder)>,
72		last: String,
73		position: Span,
74	},
75	/// Declares type as not assignable (still has interior mutability) e.g. `readonly number`
76	Readonly(Box<TypeAnnotation>, Span),
77	/// I have no idea what this is for?
78	Abstract(Box<TypeAnnotation>, Span),
79	/// Declares type as being union type of all property types e.g. `T[K]`
80	Index(Box<TypeAnnotation>, Box<TypeAnnotation>, Span),
81	/// KeyOf
82	KeyOf(Box<TypeAnnotation>, Span),
83	TypeOf(Box<VariableOrPropertyAccess>, Span),
84	Infer {
85		name: String,
86		extends: Option<Box<TypeAnnotation>>,
87		position: Span,
88	},
89	/// This is technically a special return type in TypeScript but we can make a superset behavior here
90	Asserts(Box<TypeAnnotation>, Span),
91	Extends {
92		item: Box<TypeAnnotation>,
93		extends: Box<TypeAnnotation>,
94		position: Span,
95	},
96	Is {
97		reference: IsItem,
98		is: Box<TypeAnnotation>,
99		position: Span,
100	},
101	Conditional {
102		condition: Box<TypeAnnotation>,
103		resolve_true: Box<TypeAnnotation>,
104		resolve_false: Box<TypeAnnotation>,
105		position: Span,
106	},
107	Symbol {
108		/// TODO unsure
109		unique: bool,
110		#[cfg(feature = "extras")]
111		name: Option<String>,
112		position: Span,
113	},
114	/// For operation precedence reasons
115	ParenthesizedReference(Box<TypeAnnotation>, Span),
116	/// With decorators
117	Decorated(
118		Decorator,
119		#[cfg_attr(target_family = "wasm", tsify(type = "TypeAnnotation"))] Box<Self>,
120		Span,
121	),
122	/// Allowed in certain positions
123	This(Span),
124	#[cfg_attr(feature = "self-rust-tokenize", self_tokenize_field(0))]
125	Marker(Marker<TypeAnnotation>, Span),
126}
127
128impl ListItem for TypeAnnotation {
129	type LAST = ();
130}
131
132#[derive(Debug, Clone, PartialEq)]
133#[apply(derive_ASTNode)]
134pub enum AnnotationWithBinder {
135	Annotated { name: String, ty: TypeAnnotation, position: Span },
136	NoAnnotation(TypeAnnotation),
137}
138
139impl ASTNode for AnnotationWithBinder {
140	fn get_position(&self) -> Span {
141		match self {
142			AnnotationWithBinder::Annotated { position, .. } => *position,
143			AnnotationWithBinder::NoAnnotation(ty) => ty.get_position(),
144		}
145	}
146
147	fn from_reader(
148		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
149		state: &mut crate::ParsingState,
150		options: &ParseOptions,
151	) -> ParseResult<Self> {
152		if let Some(Token(TSXToken::Colon, _)) = reader.peek_n(1) {
153			let (name, pos) =
154				token_as_identifier(reader.next().unwrap(), "tuple literal named item")?;
155			reader.next();
156			let ty = TypeAnnotation::from_reader(reader, state, options)?;
157			Ok(AnnotationWithBinder::Annotated { position: pos.union(ty.get_position()), name, ty })
158		} else {
159			TypeAnnotation::from_reader(reader, state, options).map(Self::NoAnnotation)
160		}
161	}
162
163	fn to_string_from_buffer<T: source_map::ToString>(
164		&self,
165		buf: &mut T,
166		options: &crate::ToStringOptions,
167		local: crate::LocalToStringInformation,
168	) {
169		if let AnnotationWithBinder::Annotated { name, .. } = self {
170			buf.push_str(name);
171			buf.push_str(": ");
172		}
173		self.get_inner_ref().to_string_from_buffer(buf, options, local);
174	}
175}
176
177impl AnnotationWithBinder {
178	#[must_use]
179	pub fn get_inner_ref(&self) -> &TypeAnnotation {
180		match self {
181			AnnotationWithBinder::Annotated { ty, .. } | AnnotationWithBinder::NoAnnotation(ty) => {
182				ty
183			}
184		}
185	}
186}
187
188#[derive(Debug, Clone, PartialEq)]
189#[apply(derive_ASTNode)]
190pub enum TupleElementKind {
191	Standard,
192	Spread,
193	Optional,
194}
195
196/// Reduces string allocation and type lookup overhead. This always point to the same type regardless of context (because no type is allowed to be named these)
197#[derive(Debug, Clone, PartialEq)]
198#[apply(derive_ASTNode)]
199pub enum CommonTypes {
200	String,
201	Number,
202	Boolean,
203	Any,
204	Null,
205	Undefined,
206	Unknown,
207	Never,
208}
209
210impl CommonTypes {
211	fn name(&self) -> &'static str {
212		match self {
213			CommonTypes::String => "string",
214			CommonTypes::Number => "number",
215			CommonTypes::Boolean => "boolean",
216			CommonTypes::Any => "any",
217			CommonTypes::Null => "null",
218			CommonTypes::Undefined => "undefined",
219			CommonTypes::Never => "never",
220			CommonTypes::Unknown => "unknown",
221		}
222	}
223}
224
225#[apply(derive_ASTNode)]
226#[derive(Debug, Clone, PartialEq)]
227pub enum TypeName {
228	Name(String),
229	// For `Intl.Int` or something
230	FromNamespace(Vec<String>),
231}
232
233#[apply(derive_ASTNode)]
234#[derive(Debug, Clone, PartialEq)]
235pub enum IsItem {
236	Reference(String),
237	This,
238}
239
240impl ASTNode for TypeAnnotation {
241	fn from_reader(
242		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
243		state: &mut crate::ParsingState,
244		options: &ParseOptions,
245	) -> ParseResult<Self> {
246		Self::from_reader_with_config(reader, state, options, None, None)
247	}
248
249	fn to_string_from_buffer<T: source_map::ToString>(
250		&self,
251		buf: &mut T,
252		options: &crate::ToStringOptions,
253		local: crate::LocalToStringInformation,
254	) {
255		match self {
256			Self::Marker(..) => {
257				assert!(options.expect_markers,);
258			}
259			Self::CommonName(name, _) => buf.push_str(name.name()),
260			Self::Decorated(decorator, on_type_annotation, _) => {
261				decorator.to_string_from_buffer(buf, options, local);
262				buf.push(' ');
263				on_type_annotation.to_string_from_buffer(buf, options, local);
264			}
265			Self::Name(name, _) => match name {
266				TypeName::Name(name) => {
267					buf.push_str(name);
268				}
269				TypeName::FromNamespace(namespace) => {
270					for (not_at_end, item) in namespace.iter().nendiate() {
271						buf.push_str(item);
272						if not_at_end {
273							buf.push('.');
274						}
275					}
276				}
277			},
278			Self::NameWithGenericArguments(name, arguments, _) => {
279				match name {
280					TypeName::Name(name) => {
281						buf.push_str(name);
282					}
283					TypeName::FromNamespace(namespace) => {
284						for (not_at_end, item) in namespace.iter().nendiate() {
285							buf.push_str(item);
286							if not_at_end {
287								buf.push('.');
288							}
289						}
290					}
291				}
292				to_string_bracketed(arguments, ('<', '>'), buf, options, local);
293			}
294			Self::FunctionLiteral { type_parameters, parameters, return_type, .. } => {
295				if let Some(type_parameters) = type_parameters {
296					to_string_bracketed(type_parameters, ('<', '>'), buf, options, local);
297				}
298				parameters.to_string_from_buffer(buf, options, local);
299				buf.push_str(" => ");
300				return_type.to_string_from_buffer(buf, options, local);
301			}
302			Self::BooleanLiteral(true, _) => buf.push_str("true"),
303			Self::BooleanLiteral(false, _) => buf.push_str("false"),
304			Self::This(..) => buf.push_str("this"),
305			Self::NumberLiteral(value, _) => {
306				buf.push_str(&value.to_string());
307			}
308			Self::StringLiteral(expression, quoted, _) => {
309				buf.push(quoted.as_char());
310				buf.push_str(expression.as_str());
311				buf.push(quoted.as_char());
312			}
313			Self::Union(union_members, _) => {
314				for (at_end, member) in union_members.iter().endiate() {
315					member.to_string_from_buffer(buf, options, local);
316					if !at_end {
317						buf.push_str(" | ");
318					}
319				}
320			}
321			Self::Intersection(intersection_members, _) => {
322				for (at_end, member) in intersection_members.iter().endiate() {
323					member.to_string_from_buffer(buf, options, local);
324					if !at_end {
325						buf.push_str(" & ");
326					}
327				}
328			}
329			Self::TypeOf(on, _pos) => {
330				buf.push_str("typeof ");
331				on.to_string_from_buffer(buf, options, local);
332			}
333			Self::Infer { name, extends, position: _ } => {
334				buf.push_str("infer ");
335				buf.push_str(name.as_str());
336				if let Some(ref extends) = extends {
337					buf.push_str(" extends ");
338					extends.to_string_from_buffer(buf, options, local);
339				}
340			}
341			Self::ObjectLiteral(members, _) => {
342				to_string_bracketed(members, ('{', '}'), buf, options, local);
343			}
344			Self::TupleLiteral(members, _) => {
345				to_string_bracketed(members, ('[', ']'), buf, options, local);
346			}
347			Self::Index(on, with, _) => {
348				on.to_string_from_buffer(buf, options, local);
349				buf.push('[');
350				with.to_string_from_buffer(buf, options, local);
351				buf.push(']');
352			}
353			Self::Abstract(item, _) => {
354				buf.push_str("abstract ");
355				item.to_string_from_buffer(buf, options, local);
356			}
357			Self::KeyOf(item, _) => {
358				buf.push_str("keyof ");
359				item.to_string_from_buffer(buf, options, local);
360			}
361			Self::Conditional { condition, resolve_true, resolve_false, .. } => {
362				// Same as expression::condition
363				let split_lines = crate::are_nodes_over_length(
364					[condition, resolve_true, resolve_false].iter().map(AsRef::as_ref),
365					options,
366					local,
367					Some(
368						u32::from(options.max_line_length)
369							.saturating_sub(buf.characters_on_current_line()),
370					),
371					true,
372				);
373				condition.to_string_from_buffer(buf, options, local);
374				if split_lines {
375					buf.push_new_line();
376					options.add_indent(local.depth + 1, buf);
377					buf.push_str("? ");
378				} else {
379					buf.push_str(if options.pretty { " ? " } else { "?" });
380				}
381				resolve_true.to_string_from_buffer(buf, options, local);
382				if split_lines {
383					buf.push_new_line();
384					options.add_indent(local.depth + 1, buf);
385					buf.push_str(": ");
386				} else {
387					buf.push_str(if options.pretty { " : " } else { ":" });
388				}
389				resolve_false.to_string_from_buffer(buf, options, local);
390			}
391			Self::ArrayLiteral(item, _) => {
392				item.to_string_from_buffer(buf, options, local);
393				buf.push_str("[]");
394			}
395			Self::ConstructorLiteral { parameters, type_parameters, return_type, .. } => {
396				buf.push_str("new ");
397				if let Some(type_parameters) = type_parameters {
398					to_string_bracketed(type_parameters, ('<', '>'), buf, options, local);
399				}
400				parameters.to_string_from_buffer(buf, options, local);
401				buf.push_str(" => ");
402				return_type.to_string_from_buffer(buf, options, local);
403			}
404			Self::Readonly(readonly_type, _) => {
405				buf.push_str("readonly ");
406				readonly_type.to_string_from_buffer(buf, options, local);
407			}
408			Self::ParenthesizedReference(reference, _) => {
409				buf.push('(');
410				reference.to_string_from_buffer(buf, options, local);
411				buf.push(')');
412			}
413			Self::TemplateLiteral { parts, last, .. } => {
414				buf.push('`');
415				for (static_part, dynamic_part) in parts {
416					buf.push_str_contains_new_line(static_part.as_str());
417
418					buf.push_str("${");
419					dynamic_part.to_string_from_buffer(buf, options, local);
420					buf.push('}');
421				}
422				buf.push_str_contains_new_line(last.as_str());
423				buf.push('`');
424			}
425			Self::Symbol { unique, .. } => {
426				if *unique {
427					buf.push_str("unique ");
428				}
429				buf.push_str("symbol");
430			}
431			Self::Extends { item, extends, .. } => {
432				item.to_string_from_buffer(buf, options, local);
433				buf.push_str(" extends ");
434				extends.to_string_from_buffer(buf, options, local);
435			}
436			Self::Is { reference, is, .. } => {
437				buf.push_str(match reference {
438					IsItem::Reference(reference) => reference,
439					IsItem::This => "this",
440				});
441				buf.push_str(" is ");
442				is.to_string_from_buffer(buf, options, local);
443			}
444			Self::Asserts(predicate, _pos) => {
445				buf.push_str("asserts ");
446				predicate.to_string_from_buffer(buf, options, local);
447			}
448		}
449	}
450
451	fn get_position(&self) -> Span {
452		*get_field_by_type::GetFieldByType::get(self)
453	}
454}
455
456/// For parsing
457#[derive(Clone, Copy)]
458pub(crate) enum TypeOperatorKind {
459	Union,
460	Intersection,
461	// not an implication, not an implication, not an implication
462	Function,
463	Query,
464}
465
466impl TypeAnnotation {
467	/// Also returns the local the generic arguments ran over
468	/// TODO refactor and tidy a lot of this, precedence rather than config
469	pub(crate) fn from_reader_with_config(
470		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
471		state: &mut crate::ParsingState,
472		options: &ParseOptions,
473		parent_kind: Option<TypeOperatorKind>,
474		start: Option<TokenStart>,
475	) -> ParseResult<Self> {
476		if let (true, Some(Token(peek, at))) = (options.partial_syntax, reader.peek()) {
477			let next_is_not_type_annotation_like = matches!(
478				peek,
479				TSXToken::CloseParentheses
480					| TSXToken::CloseBracket
481					| TSXToken::CloseBrace
482					| TSXToken::Comma
483					| TSXToken::OpenChevron
484			) || peek.is_assignment()
485				|| (start.map_or(false, |start| {
486					peek.is_statement_or_declaration_start()
487						&& state
488							.line_starts
489							.byte_indexes_on_different_lines(start.0 as usize, at.0 as usize)
490				}));
491
492			if next_is_not_type_annotation_like {
493				let point = start.unwrap_or(*at);
494				// take up the whole next part for checker suggestions
495				let position = point.union(source_map::End(at.0));
496				return Ok(TypeAnnotation::Marker(state.new_partial_point_marker(point), position));
497			}
498		}
499
500		while let Some(Token(TSXToken::Comment(_) | TSXToken::MultiLineComment(_), _)) =
501			reader.peek()
502		{
503			reader.next();
504		}
505
506		if let (None, Some(Token(TSXToken::BitwiseOr, _))) = (parent_kind, reader.peek()) {
507			reader.next();
508		}
509		if let (None, Some(Token(TSXToken::BitwiseAnd, _))) = (parent_kind, reader.peek()) {
510			reader.next();
511		}
512
513		let mut reference = match reader.next().ok_or_else(parse_lexing_error)? {
514			// Literals:
515			t @ Token(TSXToken::Keyword(TSXKeyword::True), _) => {
516				Self::BooleanLiteral(true, t.get_span())
517			}
518			t @ Token(TSXToken::Keyword(TSXKeyword::False), _) => {
519				Self::BooleanLiteral(false, t.get_span())
520			}
521			t @ Token(TSXToken::Keyword(TSXKeyword::This), _) => Self::This(t.get_span()),
522			Token(TSXToken::Keyword(TSXKeyword::Infer), start) => {
523				let token = reader.next().ok_or_else(parse_lexing_error)?;
524				let (name, position) = token_as_identifier(token, "infer name")?;
525				let (position, extends) = if reader
526					.conditional_next(|t| matches!(t, TSXToken::Keyword(TSXKeyword::Extends)))
527					.is_some()
528				{
529					let extends = TypeAnnotation::from_reader_with_config(
530						reader,
531						state,
532						options,
533						Some(TypeOperatorKind::Query),
534						None,
535					)?;
536					(start.union(extends.get_position()), Some(Box::new(extends)))
537				} else {
538					(start.union(position), None)
539				};
540				Self::Infer { name, extends, position }
541			}
542			Token(TSXToken::Keyword(TSXKeyword::Asserts), start) => {
543				let predicate = TypeAnnotation::from_reader_with_config(
544					reader,
545					state,
546					options,
547					parent_kind,
548					Some(start),
549				)?;
550				let position = start.union(predicate.get_position());
551				Self::Asserts(Box::new(predicate), position)
552			}
553			Token(TSXToken::Keyword(TSXKeyword::TypeOf), start) => {
554				let reference = VariableOrPropertyAccess::from_reader(reader, state, options)?;
555				let position = start.union(reference.get_position());
556				Self::TypeOf(Box::new(reference), position)
557			}
558			t @ Token(TSXToken::Keyword(TSXKeyword::Symbol), _) => {
559				let position = t.get_span();
560				#[cfg(feature = "extras")]
561				let name =
562					reader.conditional_next(|t| matches!(t, TSXToken::StringLiteral(..))).map(
563						|t| {
564							if let Token(TSXToken::StringLiteral(content, _), _) = t {
565								content
566							} else {
567								unreachable!()
568							}
569						},
570					);
571				Self::Symbol {
572					unique: false,
573					position,
574					#[cfg(feature = "extras")]
575					name,
576				}
577			}
578			t @ Token(TSXToken::Keyword(TSXKeyword::Unique), _) => {
579				let kw_pos = reader.expect_next(TSXToken::Keyword(TSXKeyword::Symbol))?;
580				let position = t.get_span().union(kw_pos.with_length("symbol".len()));
581				#[cfg(feature = "extras")]
582				let name =
583					reader.conditional_next(|t| matches!(t, TSXToken::StringLiteral(..))).map(
584						|t| {
585							if let Token(TSXToken::StringLiteral(content, _), _) = t {
586								content
587							} else {
588								unreachable!()
589							}
590						},
591					);
592				Self::Symbol {
593					unique: true,
594					position,
595					#[cfg(feature = "extras")]
596					name,
597				}
598			}
599			Token(TSXToken::NumberLiteral(value), start) => {
600				let position = start.with_length(value.len());
601				match value.parse::<NumberRepresentation>() {
602					Ok(number) => Self::NumberLiteral(number, position),
603					Err(_) => {
604						// TODO this should never happen
605						return Err(crate::ParseError::new(
606							crate::ParseErrors::InvalidNumberLiteral,
607							position,
608						));
609					}
610				}
611			}
612			Token(TSXToken::Subtract, start) => {
613				let Token(token, pos) = reader.next().ok_or_else(parse_lexing_error)?;
614				if let TSXToken::NumberLiteral(value) = token {
615					let position = pos.union(start.with_length(value.len()));
616					match value.parse::<NumberRepresentation>() {
617						Ok(number) => Self::NumberLiteral(number.neg(), position),
618						Err(_) => {
619							// TODO this should never happen
620							return Err(crate::ParseError::new(
621								crate::ParseErrors::InvalidNumberLiteral,
622								position,
623							));
624						}
625					}
626				} else {
627					return Err(ParseError::new(
628						ParseErrors::ExpectedNumberLiteral,
629						start.with_length(token.length() as usize + 1),
630					));
631				}
632			}
633			Token(TSXToken::StringLiteral(content, quoted), start) => {
634				let pos = start.with_length(content.len() + 2);
635				Self::StringLiteral(content, quoted, pos)
636			}
637			Token(TSXToken::At, pos) => {
638				let decorator = Decorator::from_reader_sub_at_symbol(reader, state, options, pos)?;
639				// TODO ...
640				let this_declaration = Self::from_reader_with_config(
641					reader,
642					state,
643					options,
644					Some(TypeOperatorKind::Query),
645					start,
646				)?;
647				let position = pos.union(this_declaration.get_position());
648				Self::Decorated(decorator, Box::new(this_declaration), position)
649			}
650			// Function literal or group
651			Token(TSXToken::OpenParentheses, start) => {
652				// Discern between group or arrow function:
653				let mut bracket_count = 1;
654				let next = reader.scan(|t, _| {
655					match t {
656						TSXToken::OpenParentheses => {
657							bracket_count += 1;
658						}
659						TSXToken::CloseParentheses => {
660							bracket_count -= 1;
661						}
662						_ => {}
663					}
664					bracket_count == 0
665				});
666				// If arrow function OR group
667				if let Some(Token(TSXToken::Arrow, _)) = next {
668					let parameters =
669						TypeAnnotationFunctionParameters::from_reader_sub_open_parenthesis(
670							reader, state, options, start,
671						)?;
672					reader.expect_next(TSXToken::Arrow)?;
673					let return_type = Self::from_reader(reader, state, options)?;
674					Self::FunctionLiteral {
675						position: start.union(return_type.get_position()),
676						type_parameters: None,
677						parameters,
678						return_type: Box::new(return_type),
679					}
680				} else {
681					let type_annotation = Self::from_reader(reader, state, options)?;
682					let position =
683						start.union(reader.expect_next_get_end(TSXToken::CloseParentheses)?);
684					Self::ParenthesizedReference(type_annotation.into(), position)
685				}
686			}
687			Token(TSXToken::OpenChevron, start) => {
688				let (type_parameters, _, _) =
689					parse_bracketed(reader, state, options, None, TSXToken::CloseChevron)?;
690				let parameters =
691					TypeAnnotationFunctionParameters::from_reader(reader, state, options)?;
692				reader.expect_next(TSXToken::Arrow)?;
693				let return_type = Self::from_reader(reader, state, options)?;
694				Self::FunctionLiteral {
695					position: start.union(return_type.get_position()),
696					type_parameters: Some(type_parameters),
697					parameters,
698					return_type: Box::new(return_type),
699				}
700			}
701			// Object literal type
702			Token(TSXToken::OpenBrace, start) => {
703				let members = parse_interface_members(reader, state, options)?;
704				let position = start.union(reader.expect_next_get_end(TSXToken::CloseBrace)?);
705				Self::ObjectLiteral(members, position)
706			}
707			// Tuple literal type
708			Token(TSXToken::OpenBracket, start) => {
709				let (members, _, end) =
710					parse_bracketed(reader, state, options, None, TSXToken::CloseBracket)?;
711				let position = start.union(end);
712				Self::TupleLiteral(members, position)
713			}
714			Token(TSXToken::TemplateLiteralStart, start) => {
715				let mut parts = Vec::new();
716				let mut last = String::new();
717				let mut end: Option<TokenEnd> = None;
718				while end.is_none() {
719					match reader.next().ok_or_else(parse_lexing_error)? {
720						Token(TSXToken::TemplateLiteralChunk(chunk), _) => {
721							last = chunk;
722						}
723						Token(TSXToken::TemplateLiteralExpressionStart, _) => {
724							let expression =
725								AnnotationWithBinder::from_reader(reader, state, options)?;
726							parts.push((std::mem::take(&mut last), expression));
727							let next = reader.next();
728							debug_assert!(matches!(
729								next,
730								Some(Token(TSXToken::TemplateLiteralExpressionEnd, _))
731							));
732						}
733						Token(TSXToken::TemplateLiteralEnd, end_position) => {
734							end = Some(TokenEnd::new(end_position.0));
735						}
736						Token(TSXToken::EOS, _) => return Err(parse_lexing_error()),
737						t => unreachable!("Token {:?}", t),
738					}
739				}
740				Self::TemplateLiteral { parts, last, position: start.union(end.unwrap()) }
741			}
742			Token(TSXToken::Keyword(TSXKeyword::Readonly), start) => {
743				let readonly_type = TypeAnnotation::from_reader_with_config(
744					reader,
745					state,
746					options,
747					Some(TypeOperatorKind::Query),
748					Some(start),
749				)?;
750				let position = start.union(readonly_type.get_position());
751				TypeAnnotation::Readonly(Box::new(readonly_type), position)
752			}
753			Token(TSXToken::Keyword(TSXKeyword::KeyOf), start) => {
754				let key_of_type = TypeAnnotation::from_reader_with_config(
755					reader,
756					state,
757					options,
758					Some(TypeOperatorKind::Query),
759					Some(start),
760				)?;
761				let position = start.union(key_of_type.get_position());
762				TypeAnnotation::KeyOf(Box::new(key_of_type), position)
763			}
764			// PLS stop adding **** to the syntax
765			Token(TSXToken::Keyword(TSXKeyword::Abstract), start) => {
766				let inner_type = TypeAnnotation::from_reader_with_config(
767					reader,
768					state,
769					options,
770					Some(TypeOperatorKind::Query),
771					Some(start),
772				)?;
773				let position = start.union(inner_type.get_position());
774				TypeAnnotation::Abstract(Box::new(inner_type), position)
775			}
776			Token(TSXToken::Keyword(TSXKeyword::New), start) => {
777				let type_parameters = reader
778					.conditional_next(|token| *token == TSXToken::OpenChevron)
779					.is_some()
780					.then(|| {
781						parse_bracketed(reader, state, options, None, TSXToken::CloseChevron)
782							.map(|(params, _, _)| params)
783					})
784					.transpose()?;
785				let parameters =
786					TypeAnnotationFunctionParameters::from_reader(reader, state, options)?;
787
788				reader.expect_next(TSXToken::Arrow)?;
789				let return_type = Self::from_reader(reader, state, options)?;
790				Self::ConstructorLiteral {
791					position: start.union(return_type.get_position()),
792					parameters,
793					type_parameters,
794					return_type: Box::new(return_type),
795				}
796			}
797			token => {
798				let (name, pos) = token_as_identifier(token, "type reference")?;
799				match name.as_str() {
800					"string" => Self::CommonName(CommonTypes::String, pos),
801					"number" => Self::CommonName(CommonTypes::Number, pos),
802					"boolean" => Self::CommonName(CommonTypes::Boolean, pos),
803					"any" => Self::CommonName(CommonTypes::Any, pos),
804					"null" => Self::CommonName(CommonTypes::Null, pos),
805					"undefined" => Self::CommonName(CommonTypes::Undefined, pos),
806					"unknown" => Self::CommonName(CommonTypes::Unknown, pos),
807					"never" => Self::CommonName(CommonTypes::Never, pos),
808					_ => Self::Name(TypeName::Name(name), pos),
809				}
810			}
811		};
812		// Namespaced name
813		if let Some(Token(TSXToken::Dot, _)) = reader.peek() {
814			let Self::Name(TypeName::Name(name), mut position) = reference else {
815				return Ok(reference);
816			};
817			let mut namespace = vec![name];
818			while reader.conditional_next(|tok| *tok == TSXToken::Dot).is_some() {
819				let (part, end) = token_as_identifier(reader.next().unwrap(), "namespace name")?;
820				namespace.push(part);
821				position = position.union(end);
822			}
823			reference = Self::Name(TypeName::FromNamespace(namespace), position);
824		}
825
826		// Generics arguments:
827		if let Some(Token(TSXToken::OpenChevron, _position)) = reader.peek() {
828			// Assert its a Self::Name
829			let Self::Name(name, start_span) = reference else {
830				let position = reader.next().unwrap().get_span();
831				return Err(ParseError::new(
832					crate::ParseErrors::TypeArgumentsNotValidOnReference,
833					position,
834				));
835			};
836			reader.next();
837			let (generic_arguments, end) =
838				generic_arguments_from_reader_sub_open_angle(reader, state, options, parent_kind)?;
839			reference =
840				Self::NameWithGenericArguments(name, generic_arguments, start_span.union(end));
841		};
842
843		// Array shorthand & indexing type references. Loops as number[][]
844		// unsure if index type can be looped
845		while reader.conditional_next(|tok| *tok == TSXToken::OpenBracket).is_some() {
846			let start = reference.get_position();
847			if let Some(Token(TSXToken::CloseBracket, _)) = reader.peek() {
848				let position = reference
849					.get_position()
850					.union(reader.next().ok_or_else(parse_lexing_error)?.get_end());
851				reference = Self::ArrayLiteral(Box::new(reference), position);
852			} else {
853				// E.g type allTypes = Person[keyof Person];
854				let indexer = TypeAnnotation::from_reader(reader, state, options)?;
855				let position = start.union(reader.expect_next_get_end(TSXToken::CloseBracket)?);
856				reference = Self::Index(Box::new(reference), Box::new(indexer), position);
857			}
858		}
859
860		if let Some(Token(TSXToken::Keyword(TSXKeyword::Is), _)) = reader.peek() {
861			fn type_annotation_as_name(
862				reference: TypeAnnotation,
863			) -> Result<(IsItem, Span), TypeAnnotation> {
864				match reference {
865					TypeAnnotation::CommonName(name, span) => {
866						Ok((IsItem::Reference(name.name().to_owned()), span))
867					}
868					TypeAnnotation::Name(TypeName::Name(name), span) => {
869						Ok((IsItem::Reference(name), span))
870					}
871					TypeAnnotation::This(span) => Ok((IsItem::This, span)),
872					_ => Err(reference),
873				}
874			}
875
876			match type_annotation_as_name(reference) {
877				Ok((item, span)) => {
878					reader.next();
879					let is_type = TypeAnnotation::from_reader_with_config(
880						reader,
881						state,
882						options,
883						Some(TypeOperatorKind::Query),
884						Some(span.get_start()),
885					)?;
886					// TODO local
887					let position = span.union(is_type.get_position());
888
889					reference =
890						TypeAnnotation::Is { reference: item, is: Box::new(is_type), position };
891				}
892				Err(reference) => {
893					return Err(ParseError::new(
894						crate::ParseErrors::InvalidLHSOfIs,
895						reference.get_position(),
896					));
897				}
898			}
899		}
900
901		if let Some(Token(TSXToken::Keyword(TSXKeyword::Extends), _)) = reader.peek() {
902			if parent_kind.is_some() {
903				return Ok(reference);
904			}
905			reader.next();
906			let extends_type = TypeAnnotation::from_reader_with_config(
907				reader,
908				state,
909				options,
910				Some(TypeOperatorKind::Query),
911				start,
912			)?;
913			// TODO local
914			let position = reference.get_position().union(extends_type.get_position());
915			reference = TypeAnnotation::Extends {
916				item: Box::new(reference),
917				extends: Box::new(extends_type),
918				position,
919			};
920		}
921
922		// Extends, intersections, unions or (special)implicit function literals
923		match reader.peek() {
924			Some(Token(TSXToken::BitwiseOr, _)) => {
925				if let Some(TypeOperatorKind::Query | TypeOperatorKind::Function) = parent_kind {
926					return Ok(reference);
927				}
928				let mut union_members = vec![reference];
929				while let Some(Token(TSXToken::BitwiseOr, _)) = reader.peek() {
930					reader.next();
931					union_members.push(Self::from_reader_with_config(
932						reader,
933						state,
934						options,
935						Some(parent_kind.unwrap_or(TypeOperatorKind::Union)),
936						start,
937					)?);
938				}
939				let position = union_members
940					.first()
941					.unwrap()
942					.get_position()
943					.union(union_members.last().unwrap().get_position());
944				Ok(Self::Union(union_members, position))
945			}
946			Some(Token(TSXToken::BitwiseAnd, _)) => {
947				if let Some(
948					TypeOperatorKind::Union | TypeOperatorKind::Query | TypeOperatorKind::Function,
949				) = parent_kind
950				{
951					return Ok(reference);
952				}
953				let mut intersection_members = vec![reference];
954				while let Some(Token(TSXToken::BitwiseAnd, _)) = reader.peek() {
955					reader.next();
956					intersection_members.push(Self::from_reader_with_config(
957						reader,
958						state,
959						options,
960						Some(parent_kind.unwrap_or(TypeOperatorKind::Intersection)),
961						start,
962					)?);
963				}
964				let position = intersection_members
965					.first()
966					.unwrap()
967					.get_position()
968					.union(intersection_members.last().unwrap().get_position());
969
970				Ok(Self::Intersection(intersection_members, position))
971			}
972			Some(Token(TSXToken::Arrow, _)) => {
973				if let Some(TypeOperatorKind::Query | TypeOperatorKind::Function) = parent_kind {
974					return Ok(reference);
975				}
976				reader.next();
977				let return_type = Self::from_reader_with_config(
978					reader,
979					state,
980					options,
981					Some(TypeOperatorKind::Function),
982					start,
983				)?;
984				let parameters_position = reference.get_position();
985				let position = parameters_position.union(return_type.get_position());
986				Ok(Self::FunctionLiteral {
987					position,
988					type_parameters: None,
989					parameters: TypeAnnotationFunctionParameters {
990						parameters: vec![TypeAnnotationFunctionParameter {
991							position,
992							name: None,
993							type_annotation: reference,
994							is_optional: false,
995							decorators: Default::default(),
996						}],
997						rest_parameter: None,
998						position: parameters_position,
999					},
1000					return_type: Box::new(return_type),
1001				})
1002			}
1003			Some(Token(TSXToken::QuestionMark, _)) => {
1004				if let Some(TypeOperatorKind::Query) = parent_kind {
1005					return Ok(reference);
1006				}
1007				reader.next();
1008				let lhs = TypeAnnotation::from_reader(reader, state, options)?;
1009				reader.expect_next(TSXToken::Colon)?;
1010				let rhs = TypeAnnotation::from_reader(reader, state, options)?;
1011				let position = reference.get_position().union(rhs.get_position());
1012				// TODO zero here ..?
1013				Ok(TypeAnnotation::Conditional {
1014					condition: Box::new(reference),
1015					resolve_true: Box::new(lhs),
1016					resolve_false: Box::new(rhs),
1017					position,
1018				})
1019			}
1020			_ => Ok(reference),
1021		}
1022	}
1023}
1024
1025/// Parses the arguments (vector of [`TypeAnnotation`]s) parsed to to a type reference or function call.
1026/// Returns arguments and the closing span.
1027/// TODO could use parse bracketed but needs to have the more complex logic inside
1028pub(crate) fn generic_arguments_from_reader_sub_open_angle(
1029	reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
1030	state: &mut crate::ParsingState,
1031	options: &ParseOptions,
1032	kind: Option<TypeOperatorKind>,
1033) -> ParseResult<(Vec<TypeAnnotation>, TokenEnd)> {
1034	let mut generic_arguments = Vec::new();
1035
1036	loop {
1037		let argument = TypeAnnotation::from_reader_with_config(reader, state, options, kind, None)?;
1038
1039		generic_arguments.push(argument);
1040
1041		// Handling for the fact that concessive chevrons are grouped into bitwise shifts
1042		// One option is to keep track of local but as a simpler way mutate the upcoming token
1043		// TODO spans
1044
1045		let peek_mut = reader.peek_mut();
1046
1047		if let Some(Token(t @ TSXToken::BitwiseShiftRight, start)) = peek_mut {
1048			let end = TokenEnd::new(start.0 + 1);
1049			start.0 += 1;
1050			*t = TSXToken::CloseChevron;
1051			return Ok((generic_arguments, end));
1052		}
1053
1054		if let Some(Token(t @ TSXToken::BitwiseShiftRightUnsigned, start)) = peek_mut {
1055			let end = TokenEnd::new(start.0 + 2);
1056			start.0 += 2;
1057			*t = TSXToken::CloseChevron;
1058			return Ok((generic_arguments, end));
1059		}
1060
1061		match reader.next().ok_or_else(parse_lexing_error)? {
1062			Token(TSXToken::Comma, _) => {}
1063			t @ Token(TSXToken::CloseChevron, _) => return Ok((generic_arguments, t.get_end())),
1064			token => {
1065				return throw_unexpected_token_with_token(
1066					token,
1067					&[TSXToken::CloseChevron, TSXToken::Comma],
1068				)
1069			}
1070		};
1071	}
1072}
1073
1074/// Mirrors [`crate::FunctionParameters`]
1075#[derive(Debug, Clone, PartialEq)]
1076#[apply(derive_ASTNode)]
1077pub struct TypeAnnotationFunctionParameters {
1078	pub parameters: Vec<TypeAnnotationFunctionParameter>,
1079	pub rest_parameter: Option<Box<TypeAnnotationSpreadFunctionParameter>>,
1080	pub position: Span,
1081}
1082
1083impl ASTNode for TypeAnnotationFunctionParameters {
1084	fn get_position(&self) -> Span {
1085		self.position
1086	}
1087
1088	fn from_reader(
1089		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
1090		state: &mut crate::ParsingState,
1091		options: &ParseOptions,
1092	) -> ParseResult<Self> {
1093		let start = reader.expect_next(TSXToken::OpenParentheses)?;
1094		Self::from_reader_sub_open_parenthesis(reader, state, options, start)
1095	}
1096
1097	fn to_string_from_buffer<T: source_map::ToString>(
1098		&self,
1099		buf: &mut T,
1100		options: &crate::ToStringOptions,
1101		local: crate::LocalToStringInformation,
1102	) {
1103		buf.push('(');
1104		for parameter in &self.parameters {
1105			if let Some(ref name) = parameter.name {
1106				name.to_string_from_buffer(buf, options, local);
1107			}
1108			if parameter.is_optional {
1109				buf.push_str("?: ");
1110			} else {
1111				buf.push_str(": ");
1112			}
1113			parameter.type_annotation.to_string_from_buffer(buf, options, local);
1114		}
1115		if let Some(ref rest_parameter) = self.rest_parameter {
1116			buf.push_str("...");
1117			buf.push_str(&rest_parameter.name);
1118			rest_parameter.type_annotation.to_string_from_buffer(buf, options, local);
1119		}
1120		buf.push(')');
1121	}
1122}
1123
1124impl TypeAnnotationFunctionParameters {
1125	pub(crate) fn from_reader_sub_open_parenthesis(
1126		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
1127		state: &mut crate::ParsingState,
1128		options: &ParseOptions,
1129		start: TokenStart,
1130	) -> ParseResult<Self> {
1131		let mut parameters = Vec::new();
1132		let mut rest_parameter = None;
1133		while !matches!(reader.peek(), Some(Token(TSXToken::CloseParentheses, _))) {
1134			while reader.peek().map_or(false, |Token(ty, _)| ty.is_comment()) {
1135				reader.next();
1136			}
1137			let mut decorators = Vec::<Decorator>::new();
1138			while let Some(Token(TSXToken::At, _)) = reader.peek() {
1139				decorators.push(Decorator::from_reader(reader, state, options)?);
1140			}
1141
1142			if let Some(Token(TSXToken::Spread, _)) = reader.peek() {
1143				let token = reader.next().unwrap();
1144				let (name, _) = token_as_identifier(
1145					reader.next().ok_or_else(parse_lexing_error)?,
1146					"spread function parameter",
1147				)?;
1148				reader.expect_next(TSXToken::Colon)?;
1149				let type_annotation = TypeAnnotation::from_reader(reader, state, options)?;
1150				rest_parameter = Some(Box::new(TypeAnnotationSpreadFunctionParameter {
1151					position: token.get_span().union(type_annotation.get_position()),
1152					name,
1153					type_annotation,
1154					decorators,
1155				}));
1156				break;
1157			}
1158
1159			let mut local = 0;
1160			let after_variable_field = reader.scan(|token, _| match token {
1161				TSXToken::OpenBracket | TSXToken::OpenBrace | TSXToken::OpenParentheses => {
1162					local += 1;
1163					false
1164				}
1165				TSXToken::CloseBracket | TSXToken::CloseBrace | TSXToken::CloseParentheses => {
1166					local -= 1;
1167					local == 0
1168				}
1169				_ => local == 0,
1170			});
1171			let name: Option<WithComment<VariableField>> =
1172				if let Some(Token(TSXToken::Colon | TSXToken::OptionalMember, _)) =
1173					after_variable_field
1174				{
1175					Some(ASTNode::from_reader(reader, state, options)?)
1176				} else {
1177					None
1178				};
1179			let is_optional = match reader.next().ok_or_else(parse_lexing_error)? {
1180				Token(TSXToken::Colon, _) => false,
1181				Token(TSXToken::OptionalMember, _) => true,
1182				token => {
1183					return throw_unexpected_token_with_token(
1184						token,
1185						&[TSXToken::Colon, TSXToken::OptionalMember],
1186					)
1187				}
1188			};
1189			let type_annotation = TypeAnnotation::from_reader(reader, state, options)?;
1190			let position = name
1191				.as_ref()
1192				.map_or(type_annotation.get_position(), ASTNode::get_position)
1193				.union(type_annotation.get_position());
1194
1195			parameters.push(TypeAnnotationFunctionParameter {
1196				decorators,
1197				name,
1198				type_annotation,
1199				is_optional,
1200				position,
1201			});
1202
1203			if reader.conditional_next(|tok| matches!(tok, TSXToken::Comma)).is_none() {
1204				break;
1205			}
1206		}
1207		let end = reader.expect_next_get_end(TSXToken::CloseParentheses)?;
1208		Ok(TypeAnnotationFunctionParameters {
1209			position: start.union(end),
1210			parameters,
1211			rest_parameter,
1212		})
1213	}
1214}
1215
1216#[derive(Debug, Clone, PartialEq)]
1217#[apply(derive_ASTNode)]
1218pub struct TypeAnnotationFunctionParameter {
1219	pub decorators: Vec<Decorator>,
1220	/// Ooh nice optional
1221	pub name: Option<WithComment<VariableField>>,
1222	pub type_annotation: TypeAnnotation,
1223	pub is_optional: bool,
1224	pub position: Span,
1225}
1226
1227#[derive(Debug, Clone, PartialEq)]
1228#[apply(derive_ASTNode)]
1229pub struct TypeAnnotationSpreadFunctionParameter {
1230	pub decorators: Vec<Decorator>,
1231	pub name: String,
1232	pub type_annotation: TypeAnnotation,
1233	pub position: Span,
1234}
1235
1236#[derive(Debug, Clone, PartialEq)]
1237#[apply(derive_ASTNode)]
1238pub struct TupleLiteralElement(pub TupleElementKind, pub AnnotationWithBinder, pub Span);
1239
1240impl ASTNode for TupleLiteralElement {
1241	fn get_position(&self) -> Span {
1242		self.2
1243	}
1244
1245	fn from_reader(
1246		reader: &mut impl TokenReader<TSXToken, crate::TokenStart>,
1247		state: &mut crate::ParsingState,
1248		options: &crate::ParseOptions,
1249	) -> ParseResult<Self> {
1250		let is_spread = reader.conditional_next(|token| matches!(token, TSXToken::Spread));
1251
1252		let annotation_with_binder = AnnotationWithBinder::from_reader(reader, state, options)?;
1253
1254		let (kind, position) = if let Some(spread) = is_spread {
1255			(TupleElementKind::Spread, spread.1.union(annotation_with_binder.get_position()))
1256		} else if let Some(trailing_question) =
1257			reader.conditional_next(|token| matches!(token, TSXToken::QuestionMark))
1258		{
1259			(
1260				TupleElementKind::Optional,
1261				annotation_with_binder.get_position().union(trailing_question.get_end()),
1262			)
1263		} else {
1264			(TupleElementKind::Standard, annotation_with_binder.get_position())
1265		};
1266
1267		Ok(Self(kind, annotation_with_binder, position))
1268	}
1269
1270	fn to_string_from_buffer<T: source_map::ToString>(
1271		&self,
1272		buf: &mut T,
1273		options: &crate::ToStringOptions,
1274		local: crate::LocalToStringInformation,
1275	) {
1276		if let TupleElementKind::Spread = self.0 {
1277			buf.push_str("...");
1278		}
1279		self.1.to_string_from_buffer(buf, options, local);
1280		if let TupleElementKind::Optional = self.0 {
1281			buf.push('?');
1282		}
1283	}
1284}
1285
1286impl ListItem for TupleLiteralElement {
1287	const EMPTY: Option<Self> = None;
1288
1289	type LAST = ();
1290}
1291
1292#[cfg(test)]
1293mod tests {
1294	use super::*;
1295	use crate::{assert_matches_ast, number::NumberRepresentation, span};
1296
1297	#[test]
1298	fn name() {
1299		assert_matches_ast!(
1300			"something",
1301			TypeAnnotation::Name(TypeName::Name(Deref @ "something"), span!(0, 9))
1302		);
1303		assert_matches_ast!("string", TypeAnnotation::CommonName(CommonTypes::String, span!(0, 6)));
1304	}
1305
1306	#[test]
1307	fn literals() {
1308		assert_matches_ast!(
1309			"\"my_string\"",
1310			TypeAnnotation::StringLiteral(Deref @ "my_string", Quoted::Double, span!(0, 11))
1311		);
1312		assert_matches_ast!(
1313			"45",
1314			TypeAnnotation::NumberLiteral(NumberRepresentation::Number { .. }, span!(0, 2))
1315		);
1316		assert_matches_ast!("true", TypeAnnotation::BooleanLiteral(true, span!(0, 4)));
1317	}
1318
1319	#[test]
1320	fn generics() {
1321		assert_matches_ast!(
1322			"Array<string>",
1323			TypeAnnotation::NameWithGenericArguments(
1324				TypeName::Name(Deref @ "Array"),
1325				Deref @ [TypeAnnotation::CommonName(CommonTypes::String, span!(6, 12))],
1326				span!(0, 13),
1327			)
1328		);
1329
1330		assert_matches_ast!(
1331			"Map<string, number>",
1332			TypeAnnotation::NameWithGenericArguments(
1333				TypeName::Name(Deref @ "Map"),
1334				Deref @
1335				[TypeAnnotation::CommonName(CommonTypes::String, span!(4, 10)), TypeAnnotation::CommonName(CommonTypes::Number, span!(12, 18))],
1336				span!(0, 19),
1337			)
1338		);
1339
1340		assert_matches_ast!(
1341			"Array<Array<string>>",
1342			TypeAnnotation::NameWithGenericArguments(
1343				TypeName::Name(Deref @ "Array"),
1344				Deref @ [TypeAnnotation::NameWithGenericArguments(
1345					TypeName::Name(Deref @ "Array"),
1346					Deref @ [TypeAnnotation::CommonName(CommonTypes::String, span!(12, 18))],
1347					span!(6, 19),
1348				)],
1349				span!(0, 20),
1350			)
1351		);
1352	}
1353
1354	#[test]
1355	fn union() {
1356		assert_matches_ast!(
1357			"string | number",
1358			TypeAnnotation::Union(
1359				Deref @
1360				[TypeAnnotation::CommonName(CommonTypes::String, span!(0, 6)), TypeAnnotation::CommonName(CommonTypes::Number, span!(9, 15))],
1361				_,
1362			)
1363		);
1364
1365		// Leading | is valid
1366		assert_matches_ast!(
1367			"| string | number",
1368			TypeAnnotation::Union(
1369				Deref @
1370				[TypeAnnotation::CommonName(CommonTypes::String, span!(2, 8)), TypeAnnotation::CommonName(CommonTypes::Number, span!(11, 17))],
1371				_,
1372			)
1373		);
1374	}
1375
1376	#[test]
1377	fn intersection() {
1378		assert_matches_ast!(
1379			"string & number",
1380			TypeAnnotation::Intersection(
1381				Deref @
1382				[TypeAnnotation::CommonName(CommonTypes::String, span!(0, 6)), TypeAnnotation::CommonName(CommonTypes::Number, span!(9, 15))],
1383				_,
1384			)
1385		);
1386	}
1387
1388	#[test]
1389	fn tuple_literal() {
1390		assert_matches_ast!(
1391			"[number, x: string]",
1392			TypeAnnotation::TupleLiteral(
1393				Deref @ [TupleLiteralElement(
1394					TupleElementKind::Standard,
1395					AnnotationWithBinder::NoAnnotation(TypeAnnotation::CommonName(
1396						CommonTypes::Number,
1397						span!(1, 7),
1398					)),
1399					_,
1400				), TupleLiteralElement(
1401					TupleElementKind::Standard,
1402					AnnotationWithBinder::Annotated {
1403						name: Deref @ "x",
1404						ty: TypeAnnotation::CommonName(CommonTypes::String, span!(12, 18)),
1405						position: _,
1406					},
1407					_,
1408				)],
1409				span!(0, 19),
1410			)
1411		);
1412	}
1413
1414	#[test]
1415	fn functions() {
1416		assert_matches_ast!(
1417			"T => T",
1418			TypeAnnotation::FunctionLiteral {
1419				type_parameters: None,
1420				parameters: TypeAnnotationFunctionParameters {
1421					parameters: Deref @ [ TypeAnnotationFunctionParameter { .. } ],
1422					..
1423				},
1424				return_type: Deref @ TypeAnnotation::Name(TypeName::Name(Deref @ "T"), span!(5, 6)),
1425				..
1426			}
1427		);
1428		// TODO more
1429	}
1430
1431	#[test]
1432	fn template_literal() {
1433		assert_matches_ast!(
1434			"`test-${X}`",
1435			TypeAnnotation::TemplateLiteral {
1436				parts: Deref @ [
1437					(
1438						Deref @ "test-",
1439						AnnotationWithBinder::NoAnnotation(TypeAnnotation::Name(TypeName::Name(Deref @ "X"), span!(8, 9)))
1440					)
1441				],
1442				..
1443			}
1444		);
1445	}
1446
1447	#[test]
1448	fn array_shorthand() {
1449		assert_matches_ast!(
1450			"string[]",
1451			TypeAnnotation::ArrayLiteral(
1452				Deref @ TypeAnnotation::CommonName(CommonTypes::String, span!(0, 6)),
1453				span!(0, 8),
1454			)
1455		);
1456		assert_matches_ast!(
1457			"(number | null)[]",
1458			TypeAnnotation::ArrayLiteral(
1459				Deref @ TypeAnnotation::ParenthesizedReference(
1460					Deref @ TypeAnnotation::Union(
1461						Deref @
1462						[TypeAnnotation::CommonName(CommonTypes::Number, span!(1, 7)), TypeAnnotation::CommonName(CommonTypes::Null, span!(10, 14))],
1463						_,
1464					),
1465					span!(0, 15),
1466				),
1467				span!(0, 17),
1468			)
1469		);
1470		assert_matches_ast!(
1471			"string[][]",
1472			TypeAnnotation::ArrayLiteral(
1473				Deref @ TypeAnnotation::ArrayLiteral(
1474					Deref @ TypeAnnotation::CommonName(CommonTypes::String, span!(0, 6)),
1475					span!(0, 8),
1476				),
1477				span!(0, 10),
1478			)
1479		);
1480	}
1481}