swc_ecma_codegen/
typescript.rs

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