Skip to main content

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