Search code examples
typescriptrustabstract-syntax-treecode-generationswc-compiler

How to generating TypeScript code with SWC


I'm hoping to use SWC in Rust to generate some TypeScript code. Unfortunately, it seems the emitter can only print JavaScript. Is this correct, or is there a way to print TypeScript? For instance, let's say we're crafting the following AST.

use swc_atoms::js_word;
use swc_common::{BytePos, Span, SyntaxContext};
use swc_ecmascript;
use swc_ecmascript::ast;

fn main() {
    let program = ast::Program::Module(ast::Module {
        body: vec![ast::ModuleItem::ModuleDecl(ast::ModuleDecl::ExportDecl(
            ast::ExportDecl {
                decl: ast::Decl::TsTypeAlias(ast::TsTypeAliasDecl {
                    span: Span::default(),
                    declare: false,
                    id: ast::Ident::new(js_word!(""), Span::default()),
                    type_params: None,
                    type_ann: Box::new(ast::TsType::TsKeywordType(ast::TsKeywordType {
                        span: Span::default(),
                        kind: ast::TsKeywordTypeKind::TsStringKeyword,
                    })),
                }),
                span: Span::default(),
            },
        ))],
        shebang: None,
        span: Span::new(BytePos(1), BytePos(1), SyntaxContext::empty()),
    });
}

How might I get the TypeScript corresponding to the program AST?


Solution

  • You need to first create a compiler (with the swc package not swc_common)

    Inside your Cargo.toml dependencies add :

    swc = { git = "https://github.com/swc-project/swc" }

    let c = swc::Compiler::new(cm.clone());
    

    Then use the print method it expose

    let ast_printed = c
            .print(
                &ast,
                Some(filename.to_str().unwrap()),
                None,
                false,
                EsVersion::Es2022,
                SourceMapsConfig::Bool(false),
                &AHashMap::default(),
                None,
                false,
                None,
            )
            .expect("Failed to print");
    

    Then you can print the .code field with println!("{}", ast_printed.code);