1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use swc_common::util::take::Take;
use swc_ecma_ast::*;
use swc_ecma_visit::{VisitMut, VisitMutWith};

pub fn ts_remover() -> impl VisitMut {
    TsRemover {}
}

struct TsRemover {}

impl VisitMut for TsRemover {
    fn visit_mut_array_pat(&mut self, p: &mut ArrayPat) {
        p.visit_mut_children_with(self);

        p.optional = false;
    }

    fn visit_mut_expr(&mut self, e: &mut Expr) {
        e.visit_mut_children_with(self);

        match e {
            Expr::TsAs(expr) => {
                *e = *expr.expr.take();
            }

            Expr::TsConstAssertion(expr) => {
                *e = *expr.expr.take();
            }

            Expr::TsTypeAssertion(expr) => {
                *e = *expr.expr.take();
            }

            Expr::TsNonNull(expr) => {
                *e = *expr.expr.take();
            }

            Expr::TsInstantiation(expr) => {
                *e = *expr.expr.take();
            }

            _ => {}
        }
    }

    fn visit_mut_ident(&mut self, i: &mut Ident) {
        i.visit_mut_children_with(self);

        i.optional = false;
    }

    fn visit_mut_module_item(&mut self, s: &mut ModuleItem) {
        s.visit_mut_children_with(self);

        match s {
            ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl {
                decl: Decl::TsInterface(_) | Decl::TsTypeAlias(_),
                ..
            }))
            | ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl {
                type_only: true, ..
            }))
            | ModuleItem::ModuleDecl(ModuleDecl::ExportNamed(NamedExport {
                type_only: true,
                ..
            })) => {
                s.take();
            }
            _ => {}
        }
    }

    fn visit_mut_object_pat(&mut self, p: &mut ObjectPat) {
        p.visit_mut_children_with(self);

        p.optional = false;
    }

    fn visit_mut_opt_ts_type(&mut self, ty: &mut Option<Box<TsType>>) {
        *ty = None;
    }

    fn visit_mut_opt_ts_type_ann(&mut self, ty: &mut Option<TsTypeAnn>) {
        *ty = None;
    }

    fn visit_mut_opt_ts_type_param_decl(&mut self, t: &mut Option<TsTypeParamDecl>) {
        *t = None;
    }

    fn visit_mut_opt_ts_type_param_instantiation(
        &mut self,
        t: &mut Option<TsTypeParamInstantiation>,
    ) {
        *t = None;
    }

    fn visit_mut_stmt(&mut self, s: &mut Stmt) {
        s.visit_mut_children_with(self);

        if let Stmt::Decl(Decl::TsTypeAlias(..) | Decl::TsInterface(..)) = s {
            s.take();
        }
    }
}