1use swc_common::{SourceMapper, Spanned};
2use swc_ecma_ast::*;
3use swc_ecma_codegen_macros::emitter;
4
5use super::{Emitter, Result};
6use crate::text_writer::WriteJs;
7
8impl<W, S: SourceMapper + SourceMapperExt> Emitter<'_, W, S>
9where
10 W: WriteJs,
11{
12 #[emitter]
13 fn emit_pat_or_ts_param_prop(&mut self, n: &ParamOrTsParamProp) -> Result {
14 match *n {
15 ParamOrTsParamProp::Param(ref n) => emit!(n),
16 ParamOrTsParamProp::TsParamProp(ref n) => emit!(n),
17 }
18 }
19
20 #[emitter]
21 fn emit_ts_array_type(&mut self, n: &TsArrayType) -> Result {
22 self.emit_leading_comments_of_span(n.span(), false)?;
23
24 emit!(n.elem_type);
25 punct!("[");
26 punct!("]");
27 }
28
29 #[emitter]
30 fn emit_ts_as_expr(&mut self, n: &TsAsExpr) -> Result {
31 self.emit_leading_comments_of_span(n.span(), false)?;
32
33 emit!(n.expr);
34
35 space!();
36 keyword!("as");
37 space!();
38
39 emit!(n.type_ann);
40 }
41
42 #[emitter]
43 fn emit_ts_satisfies_expr(&mut self, n: &TsSatisfiesExpr) -> Result {
44 self.emit_leading_comments_of_span(n.span(), false)?;
45
46 emit!(n.expr);
47
48 space!();
49 keyword!("satisfies");
50 space!();
51
52 emit!(n.type_ann);
53 }
54
55 #[emitter]
56 fn emit_ts_call_signature_decl(&mut self, n: &TsCallSignatureDecl) -> Result {
57 self.emit_leading_comments_of_span(n.span(), false)?;
58
59 emit!(n.type_params);
60
61 punct!("(");
62 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
63 punct!(")");
64
65 if let Some(type_ann) = &n.type_ann {
66 space!();
67 punct!(":");
68 space!();
69
70 emit!(type_ann);
71 }
72 }
73
74 #[emitter]
75 fn emit_ts_cond_type(&mut self, n: &TsConditionalType) -> Result {
76 self.emit_leading_comments_of_span(n.span(), false)?;
77
78 emit!(n.check_type);
79 space!();
80
81 keyword!("extends");
82 space!();
83
84 emit!(n.extends_type);
85 space!();
86 punct!("?");
87
88 space!();
89 emit!(n.true_type);
90 space!();
91
92 punct!(":");
93
94 space!();
95 emit!(n.false_type);
96 }
97
98 #[emitter]
99 fn emit_ts_constructor_signature_decl(&mut self, n: &TsConstructSignatureDecl) -> Result {
100 self.emit_leading_comments_of_span(n.span(), false)?;
101
102 keyword!("new");
103 if let Some(type_params) = &n.type_params {
104 space!();
105 emit!(type_params);
106 }
107
108 punct!("(");
109 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
110 punct!(")");
111
112 if let Some(type_ann) = &n.type_ann {
113 punct!(":");
114 space!();
115 emit!(type_ann);
116 }
117 }
118
119 #[emitter]
120 fn emit_ts_constructor_type(&mut self, n: &TsConstructorType) -> Result {
121 self.emit_leading_comments_of_span(n.span(), false)?;
122
123 if n.is_abstract {
124 keyword!("abstract");
125 space!();
126 }
127
128 keyword!("new");
129 if let Some(type_params) = &n.type_params {
130 space!();
131 emit!(type_params);
132 }
133
134 punct!("(");
135 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
136 punct!(")");
137
138 formatting_space!();
139 punct!("=>");
140 formatting_space!();
141
142 emit!(n.type_ann)
143 }
144
145 #[emitter]
146 fn emit_ts_entity_name(&mut self, n: &TsEntityName) -> Result {
147 self.emit_leading_comments_of_span(n.span(), false)?;
148
149 match n {
150 TsEntityName::TsQualifiedName(n) => {
151 emit!(n);
152 }
153 TsEntityName::Ident(n) => emit!(n),
154 }
155 }
156
157 #[emitter]
158 fn emit_ts_enum_decl(&mut self, n: &TsEnumDecl) -> Result {
159 self.emit_leading_comments_of_span(n.span(), false)?;
160
161 if n.declare {
162 keyword!("declare");
163 space!();
164 }
165
166 if n.is_const {
167 keyword!("const");
168 space!();
169 }
170
171 keyword!("enum");
172 space!();
173
174 emit!(n.id);
175 formatting_space!();
176
177 punct!("{");
178
179 self.emit_list(n.span, Some(&n.members), ListFormat::EnumMembers)?;
180
181 punct!("}");
182 }
183
184 #[emitter]
185 fn emit_ts_enum_member(&mut self, n: &TsEnumMember) -> Result {
186 self.emit_leading_comments_of_span(n.span(), false)?;
187
188 emit!(n.id);
189
190 if let Some(init) = &n.init {
191 formatting_space!();
192 punct!("=");
193 formatting_space!();
194 emit!(init);
195 }
196 }
197
198 #[emitter]
199 fn emit_ts_enum_member_id(&mut self, n: &TsEnumMemberId) -> Result {
200 match n {
201 TsEnumMemberId::Ident(n) => emit!(n),
202 TsEnumMemberId::Str(n) => emit!(n),
203 }
204 }
205
206 #[emitter]
207 fn emit_ts_export_assignment(&mut self, n: &TsExportAssignment) -> Result {
208 self.emit_leading_comments_of_span(n.span(), false)?;
209
210 keyword!("export");
211 formatting_space!();
212 punct!("=");
213 formatting_space!();
214 emit!(n.expr);
215 }
216
217 #[emitter]
218 fn emit_ts_expr_with_type_args(&mut self, n: &TsExprWithTypeArgs) -> Result {
219 self.emit_leading_comments_of_span(n.span(), false)?;
220
221 emit!(n.expr);
222
223 emit!(n.type_args);
224 }
225
226 #[emitter]
227 fn emit_ts_external_module_ref(&mut self, n: &TsExternalModuleRef) -> Result {
228 self.emit_leading_comments_of_span(n.span(), false)?;
229
230 keyword!("require");
231 punct!("(");
232 emit!(n.expr);
233 punct!(")");
234 }
235
236 #[emitter]
237 fn emit_ts_fn_or_constructor_type(&mut self, n: &TsFnOrConstructorType) -> Result {
238 self.emit_leading_comments_of_span(n.span(), false)?;
239
240 match n {
241 TsFnOrConstructorType::TsFnType(n) => emit!(n),
242 TsFnOrConstructorType::TsConstructorType(n) => emit!(n),
243 }
244 }
245
246 #[emitter]
247 fn emit_ts_fn_param(&mut self, n: &TsFnParam) -> Result {
248 match n {
249 TsFnParam::Ident(n) => emit!(n),
250 TsFnParam::Array(n) => emit!(n),
251 TsFnParam::Rest(n) => emit!(n),
252 TsFnParam::Object(n) => emit!(n),
253 }
254 }
255
256 #[emitter]
257 fn emit_ts_fn_type(&mut self, n: &TsFnType) -> Result {
258 self.emit_leading_comments_of_span(n.span(), false)?;
259
260 emit!(n.type_params);
261
262 punct!("(");
263 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
264 punct!(")");
265
266 formatting_space!();
267 punct!("=>");
268 formatting_space!();
269
270 emit!(n.type_ann);
271 }
272
273 #[emitter]
274 fn emit_ts_import_equals_decl(&mut self, n: &TsImportEqualsDecl) -> Result {
275 self.emit_leading_comments_of_span(n.span(), false)?;
276
277 if n.is_export {
278 keyword!("export");
279 space!();
280 }
281
282 keyword!("import");
283 space!();
284
285 if n.is_type_only {
286 keyword!("type");
287 space!();
288 }
289
290 emit!(n.id);
291
292 formatting_space!();
293
294 punct!("=");
295 formatting_space!();
296
297 emit!(n.module_ref);
298 formatting_semi!();
299 }
300
301 #[emitter]
302 fn emit_ts_index_signature(&mut self, n: &TsIndexSignature) -> Result {
303 self.emit_leading_comments_of_span(n.span(), false)?;
304
305 if n.readonly {
306 keyword!("readonly");
307 formatting_space!();
308 }
309
310 punct!("[");
311 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
312 punct!("]");
313
314 if let Some(type_ann) = &n.type_ann {
315 punct!(":");
316 formatting_space!();
317 emit!(type_ann);
318 }
319 }
320
321 #[emitter]
322 fn emit_ts_index_accessed_type(&mut self, n: &TsIndexedAccessType) -> Result {
323 self.emit_leading_comments_of_span(n.span(), false)?;
324
325 emit!(n.obj_type);
326
327 punct!("[");
328 emit!(n.index_type);
329 punct!("]");
330 }
331
332 #[emitter]
333 fn emit_ts_infer_type(&mut self, n: &TsInferType) -> Result {
334 self.emit_leading_comments_of_span(n.span(), false)?;
335
336 keyword!("infer");
337 space!();
338 emit!(n.type_param);
339 }
340
341 #[emitter]
342 fn emit_ts_interface_body(&mut self, n: &TsInterfaceBody) -> Result {
343 self.emit_leading_comments_of_span(n.span(), false)?;
344
345 punct!("{");
346
347 self.emit_list(n.span, Some(&n.body), ListFormat::InterfaceMembers)?;
348
349 punct!("}");
350 }
351
352 #[emitter]
353 fn emit_ts_interface_decl(&mut self, n: &TsInterfaceDecl) -> Result {
354 self.emit_leading_comments_of_span(n.span(), false)?;
355
356 if n.declare {
357 keyword!("declare");
358 space!();
359 }
360
361 keyword!("interface");
362 space!();
363
364 emit!(n.id);
365
366 if let Some(type_params) = &n.type_params {
367 emit!(type_params);
368 }
369
370 if !n.extends.is_empty() {
371 space!();
372
373 keyword!("extends");
374
375 space!();
376
377 self.emit_list(n.span, Some(&n.extends), ListFormat::HeritageClauseTypes)?;
378 }
379
380 formatting_space!();
381
382 emit!(n.body);
383 }
384
385 #[emitter]
386 fn emit_ts_intersection_type(&mut self, n: &TsIntersectionType) -> Result {
387 self.emit_leading_comments_of_span(n.span(), false)?;
388
389 self.emit_list(
390 n.span,
391 Some(&n.types),
392 ListFormat::IntersectionTypeConstituents,
393 )?;
394 }
395
396 #[emitter]
397 fn emit_ts_keyword_type(&mut self, n: &TsKeywordType) -> Result {
398 self.emit_leading_comments_of_span(n.span(), false)?;
399
400 match n.kind {
401 TsKeywordTypeKind::TsAnyKeyword => keyword!(n.span, "any"),
402 TsKeywordTypeKind::TsUnknownKeyword => keyword!(n.span, "unknown"),
403 TsKeywordTypeKind::TsNumberKeyword => keyword!(n.span, "number"),
404 TsKeywordTypeKind::TsObjectKeyword => keyword!(n.span, "object"),
405 TsKeywordTypeKind::TsBooleanKeyword => keyword!(n.span, "boolean"),
406 TsKeywordTypeKind::TsBigIntKeyword => keyword!(n.span, "bigint"),
407 TsKeywordTypeKind::TsStringKeyword => keyword!(n.span, "string"),
408 TsKeywordTypeKind::TsSymbolKeyword => keyword!(n.span, "symbol"),
409 TsKeywordTypeKind::TsVoidKeyword => keyword!(n.span, "void"),
410 TsKeywordTypeKind::TsUndefinedKeyword => keyword!(n.span, "undefined"),
411 TsKeywordTypeKind::TsNullKeyword => keyword!(n.span, "null"),
412 TsKeywordTypeKind::TsNeverKeyword => keyword!(n.span, "never"),
413 TsKeywordTypeKind::TsIntrinsicKeyword => keyword!(n.span, "intrinsic"),
414 }
415 }
416
417 #[emitter]
418 fn emit_ts_lit(&mut self, n: &TsLit) -> Result {
419 match n {
420 TsLit::BigInt(n) => emit!(n),
421 TsLit::Number(n) => emit!(n),
422 TsLit::Str(n) => emit!(n),
423 TsLit::Bool(n) => emit!(n),
424 TsLit::Tpl(n) => emit!(n),
425 }
426 }
427
428 #[emitter]
429 fn emit_ts_tpl_lit(&mut self, node: &TsTplLitType) -> Result {
430 debug_assert!(node.quasis.len() == node.types.len() + 1);
431
432 self.emit_leading_comments_of_span(node.span(), false)?;
433
434 punct!("`");
435
436 for i in 0..(node.quasis.len() + node.types.len()) {
437 if i % 2 == 0 {
438 emit!(node.quasis[i / 2]);
439 } else {
440 punct!("${");
441 emit!(node.types[i / 2]);
442 punct!("}");
443 }
444 }
445
446 punct!("`");
447 }
448
449 #[emitter]
450 fn emit_ts_lit_type(&mut self, n: &TsLitType) -> Result {
451 self.emit_leading_comments_of_span(n.span(), false)?;
452
453 emit!(n.lit);
454 }
455
456 #[emitter]
457 fn emit_ts_mapped_type(&mut self, n: &TsMappedType) -> Result {
458 self.emit_leading_comments_of_span(n.span(), false)?;
459
460 punct!("{");
461 self.wr.write_line()?;
462 self.wr.increase_indent()?;
463
464 match n.readonly {
465 None => {}
466 Some(tpm) => match tpm {
467 TruePlusMinus::True => {
468 keyword!("readonly");
469 space!();
470 }
471 TruePlusMinus::Plus => {
472 punct!("+");
473 keyword!("readonly");
474 space!();
475 }
476 TruePlusMinus::Minus => {
477 punct!("-");
478 keyword!("readonly");
479 space!();
480 }
481 },
482 }
483
484 punct!("[");
485
486 emit!(n.type_param.name);
487
488 if let Some(constraints) = &n.type_param.constraint {
489 space!();
490 keyword!("in");
491 space!();
492 emit!(constraints);
493 }
494
495 if let Some(default) = &n.type_param.default {
496 formatting_space!();
497 punct!("=");
498 formatting_space!();
499 emit!(default);
500 }
501
502 if let Some(name_type) = &n.name_type {
503 space!();
504 keyword!("as");
505 space!();
506 emit!(name_type);
507 }
508
509 punct!("]");
510
511 match n.optional {
512 None => {}
513 Some(tpm) => match tpm {
514 TruePlusMinus::True => {
515 punct!("?");
516 }
517 TruePlusMinus::Plus => {
518 punct!("+");
519 punct!("?");
520 }
521 TruePlusMinus::Minus => {
522 punct!("-");
523 punct!("?");
524 }
525 },
526 }
527
528 if let Some(type_ann) = &n.type_ann {
529 punct!(":");
530 space!();
531 emit!(type_ann);
532 }
533
534 formatting_semi!();
535
536 self.wr.write_line()?;
537 self.wr.decrease_indent()?;
538 punct!("}");
539 }
540
541 #[emitter]
542 fn emit_ts_method_signature(&mut self, n: &TsMethodSignature) -> Result {
543 self.emit_leading_comments_of_span(n.span(), false)?;
544
545 if n.computed {
546 punct!("[");
547 emit!(n.key);
548 punct!("]");
549 } else {
550 emit!(n.key)
551 }
552
553 if n.optional {
554 punct!("?");
555 }
556
557 if let Some(type_params) = &n.type_params {
558 emit!(type_params);
559 }
560
561 punct!("(");
562 self.emit_list(n.span, Some(&n.params), ListFormat::Parameters)?;
563 punct!(")");
564
565 if let Some(ref type_ann) = n.type_ann {
566 punct!(":");
567 formatting_space!();
568 emit!(type_ann);
569 }
570 }
571
572 #[emitter]
573 fn emit_ts_module_block(&mut self, n: &TsModuleBlock) -> Result {
574 self.emit_list(n.span, Some(&n.body), ListFormat::SourceFileStatements)?;
575 self.emit_leading_comments_of_span(n.span(), false)?;
576 }
577
578 #[emitter]
579 fn emit_ts_module_decl(&mut self, n: &TsModuleDecl) -> Result {
580 self.emit_leading_comments_of_span(n.span(), false)?;
581
582 if n.declare {
583 keyword!("declare");
584 space!();
585 }
586
587 if n.global {
588 keyword!("global");
589 } else {
590 match &n.id {
591 TsModuleName::Ident(_) => keyword!("namespace"),
594 TsModuleName::Str(_) => keyword!("module"),
595 }
596 space!();
597 emit!(n.id);
598 }
599
600 if let Some(mut body) = n.body.as_ref() {
601 while let TsNamespaceBody::TsNamespaceDecl(decl) = body {
602 punct!(".");
603 emit!(decl.id);
604 body = &*decl.body;
605 }
606 formatting_space!();
607 emit!(body);
608 }
609 }
610
611 #[emitter]
612 fn emit_ts_module_name(&mut self, n: &TsModuleName) -> Result {
613 match n {
614 TsModuleName::Ident(n) => emit!(n),
615 TsModuleName::Str(n) => emit!(n),
616 }
617 }
618
619 #[emitter]
620 fn emit_ts_module_ref(&mut self, n: &TsModuleRef) -> Result {
621 self.emit_leading_comments_of_span(n.span(), false)?;
622
623 match n {
624 TsModuleRef::TsEntityName(n) => emit!(n),
625 TsModuleRef::TsExternalModuleRef(n) => emit!(n),
626 }
627 }
628
629 #[emitter]
630 fn emit_ts_ns_body(&mut self, n: &TsNamespaceBody) -> Result {
631 self.emit_leading_comments_of_span(n.span(), false)?;
632
633 punct!("{");
634 self.wr.increase_indent()?;
635 match n {
636 TsNamespaceBody::TsModuleBlock(n) => emit!(n),
637 TsNamespaceBody::TsNamespaceDecl(n) => emit!(n),
638 }
639 self.wr.decrease_indent()?;
640 punct!("}");
641 }
642
643 #[emitter]
644 fn emit_ts_ns_decl(&mut self, n: &TsNamespaceDecl) -> Result {
645 self.emit_leading_comments_of_span(n.span(), false)?;
646
647 if n.declare {
648 keyword!("declare");
649 space!();
650 }
651
652 keyword!("namespace");
653 space!();
654 emit!(n.id);
655 formatting_space!();
656
657 emit!(n.body);
658 }
659
660 #[emitter]
661 fn emit_ts_ns_export_decl(&mut self, n: &TsNamespaceExportDecl) -> Result {
662 self.emit_leading_comments_of_span(n.span(), false)?;
663
664 keyword!("export");
665 space!();
666 punct!("=");
667 space!();
668 emit!(n.id);
669 }
670
671 #[emitter]
672 fn emit_ts_non_null_expr(&mut self, n: &TsNonNullExpr) -> Result {
673 self.emit_leading_comments_of_span(n.span(), false)?;
674
675 emit!(n.expr);
676 punct!("!")
677 }
678
679 #[emitter]
680 fn emit_ts_optional_type(&mut self, n: &TsOptionalType) -> Result {
681 self.emit_leading_comments_of_span(n.span(), false)?;
682
683 emit!(n.type_ann);
684 punct!("?");
685 }
686
687 #[emitter]
688 fn emit_ts_param_prop(&mut self, n: &TsParamProp) -> Result {
689 self.emit_leading_comments_of_span(n.span(), false)?;
690
691 self.emit_list(n.span, Some(&n.decorators), ListFormat::Decorators)?;
692
693 self.emit_accessibility(n.accessibility)?;
694
695 if n.is_override {
696 keyword!("override");
697 space!();
698 }
699
700 if n.readonly {
701 keyword!("readonly");
702 space!();
703 }
704
705 emit!(n.param);
706 }
707
708 #[emitter]
709 fn emit_ts_param_prop_param(&mut self, n: &TsParamPropParam) -> Result {
710 self.emit_leading_comments_of_span(n.span(), false)?;
711
712 match n {
713 TsParamPropParam::Ident(n) => emit!(n),
714 TsParamPropParam::Assign(n) => emit!(n),
715 }
716 }
717
718 #[emitter]
719 fn emit_ts_paren_type(&mut self, n: &TsParenthesizedType) -> Result {
720 self.emit_leading_comments_of_span(n.span(), false)?;
721
722 punct!("(");
723 emit!(n.type_ann);
724 punct!(")");
725 }
726
727 #[emitter]
728 fn emit_ts_property_signature(&mut self, n: &TsPropertySignature) -> Result {
729 self.emit_leading_comments_of_span(n.span(), false)?;
730
731 if n.readonly {
732 keyword!("readonly");
733 space!();
734 }
735
736 if n.computed {
737 punct!("[");
738 emit!(n.key);
739 punct!("]");
740 } else {
741 emit!(n.key);
742 }
743
744 if n.optional {
745 punct!("?");
746 }
747
748 if let Some(type_ann) = &n.type_ann {
753 punct!(":");
754 formatting_space!();
755 emit!(type_ann);
756 }
757 }
758
759 #[emitter]
760 fn emit_ts_qualified_name(&mut self, n: &TsQualifiedName) -> Result {
761 self.emit_leading_comments_of_span(n.span(), false)?;
762
763 emit!(n.left);
764 punct!(".");
765 emit!(n.right);
766 }
767
768 #[emitter]
769 fn emit_ts_rest_type(&mut self, n: &TsRestType) -> Result {
770 self.emit_leading_comments_of_span(n.span(), false)?;
771
772 punct!("...");
773 emit!(n.type_ann);
774 }
775
776 #[emitter]
777 fn emit_ts_this_type(&mut self, n: &TsThisType) -> Result {
778 self.emit_leading_comments_of_span(n.span(), false)?;
779
780 keyword!(n.span, "this");
781 }
782
783 #[emitter]
784 fn emit_ts_this_type_or_ident(&mut self, n: &TsThisTypeOrIdent) -> Result {
785 self.emit_leading_comments_of_span(n.span(), false)?;
786
787 match n {
788 TsThisTypeOrIdent::TsThisType(n) => emit!(n),
789 TsThisTypeOrIdent::Ident(n) => emit!(n),
790 }
791 }
792
793 #[emitter]
794 fn emit_ts_tuple_type(&mut self, n: &TsTupleType) -> Result {
795 self.emit_leading_comments_of_span(n.span(), false)?;
796
797 punct!("[");
798 self.emit_list(n.span, Some(&n.elem_types), ListFormat::TupleTypeElements)?;
799 punct!("]");
800 }
801
802 #[emitter]
803 fn emit_ts_tuple_element(&mut self, n: &TsTupleElement) -> Result {
804 self.emit_leading_comments_of_span(n.span(), false)?;
805
806 if let Some(label) = &n.label {
807 emit!(label);
808 punct!(":");
809 formatting_space!();
810 }
811
812 emit!(n.ty)
813 }
814
815 #[emitter]
816 fn emit_ts_type(&mut self, n: &TsType) -> Result {
817 match n {
818 TsType::TsKeywordType(n) => emit!(n),
819 TsType::TsThisType(n) => emit!(n),
820 TsType::TsFnOrConstructorType(n) => emit!(n),
821 TsType::TsTypeRef(n) => emit!(n),
822 TsType::TsTypeQuery(n) => emit!(n),
823 TsType::TsTypeLit(n) => emit!(n),
824 TsType::TsArrayType(n) => emit!(n),
825 TsType::TsTupleType(n) => emit!(n),
826 TsType::TsOptionalType(n) => emit!(n),
827 TsType::TsRestType(n) => emit!(n),
828 TsType::TsUnionOrIntersectionType(n) => emit!(n),
829 TsType::TsConditionalType(n) => emit!(n),
830 TsType::TsInferType(n) => emit!(n),
831 TsType::TsParenthesizedType(n) => emit!(n),
832 TsType::TsTypeOperator(n) => emit!(n),
833 TsType::TsIndexedAccessType(n) => emit!(n),
834 TsType::TsMappedType(n) => emit!(n),
835 TsType::TsLitType(n) => emit!(n),
836 TsType::TsTypePredicate(n) => emit!(n),
837 TsType::TsImportType(n) => emit!(n),
838 }
839 }
840
841 #[emitter]
842 fn emit_ts_import_type(&mut self, n: &TsImportType) -> Result {
843 self.emit_leading_comments_of_span(n.span(), false)?;
844
845 keyword!("import");
846 punct!("(");
847 emit!(n.arg);
848 if let Some(attributes) = &n.attributes {
849 punct!(",");
850 formatting_space!();
851 emit!(attributes);
852 }
853 punct!(")");
854
855 if let Some(n) = &n.qualifier {
856 punct!(".");
857 emit!(n);
858 }
859
860 emit!(n.type_args);
861 }
862
863 #[emitter]
864 fn emit_ts_import_call_options(&mut self, n: &TsImportCallOptions) -> Result {
865 punct!("{");
866 if !self.cfg.minify {
867 self.wr.write_line()?;
868 self.wr.increase_indent()?;
869 }
870
871 keyword!("with");
872 punct!(":");
873 formatting_space!();
874 emit!(n.with);
875
876 if !self.cfg.minify {
877 self.wr.decrease_indent()?;
878 self.wr.write_line()?;
879 }
880 punct!("}");
881 }
882
883 #[emitter]
884 fn emit_ts_type_alias_decl(&mut self, n: &TsTypeAliasDecl) -> Result {
885 self.emit_leading_comments_of_span(n.span(), false)?;
886
887 if n.declare {
888 keyword!("declare");
889 space!();
890 }
891
892 keyword!("type");
893
894 space!();
895
896 emit!(n.id);
897 if let Some(type_params) = &n.type_params {
898 emit!(type_params);
899 }
900 formatting_space!();
901
902 punct!("=");
903
904 formatting_space!();
905
906 emit!(n.type_ann);
907
908 formatting_semi!();
909 }
910
911 #[emitter]
912 fn emit_ts_type_ann(&mut self, n: &TsTypeAnn) -> Result {
913 self.emit_leading_comments_of_span(n.span(), false)?;
914
915 emit!(n.type_ann)
916 }
917
918 #[emitter]
919 fn emit_ts_type_assertion(&mut self, n: &TsTypeAssertion) -> Result {
920 self.emit_leading_comments_of_span(n.span(), false)?;
921
922 punct!("<");
923 emit!(n.type_ann);
924 punct!(">");
925 emit!(n.expr);
926 }
927
928 #[emitter]
929 fn emit_ts_const_assertion(&mut self, n: &TsConstAssertion) -> Result {
930 self.emit_leading_comments_of_span(n.span(), false)?;
931
932 emit!(n.expr);
933
934 space!();
935 keyword!("as");
936 space!();
937 keyword!("const");
938 }
939
940 #[emitter]
941 fn emit_ts_type_element(&mut self, n: &TsTypeElement) -> Result {
942 match n {
943 TsTypeElement::TsCallSignatureDecl(n) => emit!(n),
944 TsTypeElement::TsConstructSignatureDecl(n) => emit!(n),
945 TsTypeElement::TsPropertySignature(n) => emit!(n),
946 TsTypeElement::TsMethodSignature(n) => emit!(n),
947 TsTypeElement::TsIndexSignature(n) => emit!(n),
948 TsTypeElement::TsGetterSignature(n) => {
949 emit!(n)
950 }
951 TsTypeElement::TsSetterSignature(n) => {
952 emit!(n)
953 }
954 }
955 formatting_semi!();
956 }
957
958 #[emitter]
959 fn emit_ts_getter_signature(&mut self, n: &TsGetterSignature) -> Result {
960 keyword!("get");
961 space!();
962
963 if n.computed {
964 punct!("[");
965 emit!(n.key);
966 punct!("]");
967 } else {
968 emit!(n.key)
969 }
970
971 punct!("(");
972 punct!(")");
973
974 if let Some(ty) = &n.type_ann {
975 punct!(":");
976 formatting_space!();
977
978 emit!(ty.type_ann);
979 }
980 }
981
982 #[emitter]
983 fn emit_ts_setter_signature(&mut self, n: &TsSetterSignature) -> Result {
984 keyword!("set");
985 space!();
986
987 if n.computed {
988 punct!("[");
989 emit!(n.key);
990 punct!("]");
991 } else {
992 emit!(n.key)
993 }
994
995 punct!("(");
996 emit!(n.param);
997 punct!(")");
998 }
999
1000 #[emitter]
1001 fn emit_ts_type_lit(&mut self, n: &TsTypeLit) -> Result {
1002 self.emit_leading_comments_of_span(n.span(), false)?;
1003
1004 punct!("{");
1005 self.emit_list(
1006 n.span,
1007 Some(&n.members),
1008 ListFormat::MultiLineTypeLiteralMembers,
1009 )?;
1010 punct!("}");
1011 }
1012
1013 #[emitter]
1014 fn emit_ts_type_operator(&mut self, n: &TsTypeOperator) -> Result {
1015 self.emit_leading_comments_of_span(n.span(), false)?;
1016
1017 match n.op {
1018 TsTypeOperatorOp::KeyOf => keyword!("keyof"),
1019 TsTypeOperatorOp::Unique => keyword!("unique"),
1020 TsTypeOperatorOp::ReadOnly => keyword!("readonly"),
1021 }
1022 space!();
1023 emit!(n.type_ann);
1024 }
1025
1026 #[emitter]
1027 fn emit_ts_type_param(&mut self, n: &TsTypeParam) -> Result {
1028 self.emit_leading_comments_of_span(n.span(), false)?;
1029
1030 if n.is_const {
1031 keyword!("const");
1032 space!();
1033 }
1034
1035 if n.is_in {
1036 keyword!("in");
1037 space!();
1038 }
1039
1040 if n.is_out {
1041 keyword!("out");
1042 space!();
1043 }
1044
1045 emit!(n.name);
1046
1047 if let Some(constraints) = &n.constraint {
1048 space!();
1049 keyword!("extends");
1050 space!();
1051 emit!(constraints);
1052 }
1053
1054 if let Some(default) = &n.default {
1055 formatting_space!();
1056 punct!("=");
1057 formatting_space!();
1058 emit!(default);
1059 }
1060 }
1061
1062 #[emitter]
1063 fn emit_ts_type_param_decl(&mut self, n: &TsTypeParamDecl) -> Result {
1064 self.emit_leading_comments_of_span(n.span(), false)?;
1065
1066 punct!("<");
1067
1068 self.emit_list(n.span, Some(&n.params), ListFormat::TypeParameters)?;
1069
1070 punct!(">");
1071 }
1072
1073 #[emitter]
1074 fn emit_ts_type_param_instantiation(&mut self, n: &TsTypeParamInstantiation) -> Result {
1075 self.emit_leading_comments_of_span(n.span(), false)?;
1076
1077 punct!("<");
1078 self.emit_list(n.span, Some(&n.params), ListFormat::TypeParameters)?;
1079
1080 punct!(">");
1081 }
1082
1083 #[emitter]
1084 fn emit_ts_type_predicate(&mut self, n: &TsTypePredicate) -> Result {
1085 self.emit_leading_comments_of_span(n.span(), false)?;
1086
1087 if n.asserts {
1088 keyword!("asserts");
1089 space!();
1090 }
1091
1092 emit!(n.param_name);
1093
1094 if let Some(type_ann) = &n.type_ann {
1095 space!();
1096 keyword!("is");
1097 space!();
1098 emit!(type_ann);
1099 }
1100 }
1101
1102 #[emitter]
1103 fn emit_ts_type_query(&mut self, n: &TsTypeQuery) -> Result {
1104 self.emit_leading_comments_of_span(n.span(), false)?;
1105
1106 keyword!("typeof");
1107 space!();
1108 emit!(n.expr_name);
1109 emit!(n.type_args);
1110 }
1111
1112 #[emitter]
1113 fn emit_ts_type_query_expr(&mut self, n: &TsTypeQueryExpr) -> Result {
1114 match n {
1115 TsTypeQueryExpr::TsEntityName(n) => emit!(n),
1116 TsTypeQueryExpr::Import(n) => emit!(n),
1117 }
1118 }
1119
1120 #[emitter]
1121 fn emit_ts_type_ref(&mut self, n: &TsTypeRef) -> Result {
1122 self.emit_leading_comments_of_span(n.span(), false)?;
1123
1124 emit!(n.type_name);
1125
1126 if let Some(n) = &n.type_params {
1127 punct!("<");
1128 self.emit_list(n.span, Some(&n.params), ListFormat::TypeArguments)?;
1129 punct!(">");
1130 }
1131 }
1132
1133 #[emitter]
1134 fn emit_ts_union_or_intersection_type(&mut self, n: &TsUnionOrIntersectionType) -> Result {
1135 match n {
1136 TsUnionOrIntersectionType::TsUnionType(n) => emit!(n),
1137 TsUnionOrIntersectionType::TsIntersectionType(n) => emit!(n),
1138 }
1139 }
1140
1141 #[emitter]
1142 fn emit_ts_union_type(&mut self, n: &TsUnionType) -> Result {
1143 self.emit_leading_comments_of_span(n.span(), false)?;
1144
1145 self.emit_list(n.span, Some(&n.types), ListFormat::UnionTypeConstituents)?;
1146 }
1147
1148 #[emitter]
1149 fn emit_ts_instantiation(&mut self, n: &TsInstantiation) -> Result {
1150 self.emit_leading_comments_of_span(n.span(), false)?;
1151
1152 emit!(n.expr);
1153
1154 emit!(n.type_args);
1155 }
1156}
1157
1158#[cfg(test)]
1159mod tests {
1160 use crate::tests::assert_min_typescript;
1161
1162 #[test]
1163 fn qualified_type() {
1164 assert_min_typescript(
1165 "var memory: WebAssembly.Memory;",
1166 "var memory:WebAssembly.Memory",
1167 );
1168 }
1169
1170 #[test]
1171 fn type_arg() {
1172 assert_min_typescript("do_stuff<T>()", "do_stuff<T>()");
1173 }
1174
1175 #[test]
1176 fn no_type_arg() {
1177 assert_min_typescript("do_stuff()", "do_stuff()");
1178 }
1179}