swc_ecma_codegen/
typescript.rs

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