swc_ecma_codegen/
typescript.rs

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