付延伟
付延伟

Reputation: 93

how to use require('typescript').transform?

const ts = require('typescript');

let template = `
         let hello: string = 'hello,world';
`
ts.transform

How to convert strings in the above operation?

Upvotes: 3

Views: 214

Answers (1)

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249466

You can use the transpile function. This will allow you to compile an arbitrary string:

import * as typescript from 'typescript';  

let template = `
         let hello: string = 'hello,world';
         class test{}
`
let errors : typescript.Diagnostic[] = []
let result = typescript.transpile(template, {}, undefined, errors);

// The result
console.log(result);
// The erorrs
for(let err of errors) console.log(err.messageText);

Edit

The solution above works, but it only checks for syntactical errors not for semantic errors. A version which does module resolution and will check for semantic errors would be:

function transpileWithAllErrors(input: string, compilerOptions?: typescript.CompilerOptions, fileName: string = "dynamic.ts", diagnostics?: typescript.Diagnostic[]): string {
    let result: string;
    let host = typescript.createCompilerHost({});
    let sourceFile = typescript.createSourceFile(fileName, template, typescript.ScriptTarget.ES5);
    let orginalGetSourceFile = host.getSourceFile;
    host.getSourceFile = (file, languageVersion, onError, shouldCreateNewSourceFile) =>
        file == fileName ?
            sourceFile :
            orginalGetSourceFile(file, languageVersion, onError, shouldCreateNewSourceFile);

    host.getCurrentDirectory = () => "";
    host.getDefaultLibLocation = () => "node_modules/typescript/lib";
    host.getDefaultLibFileName = () => "node_modules/typescript/lib/lib.d.ts";

    let program = typescript.createProgram([fileName], {}, host);

    // Capture output, 
    host.writeFile = (wFileName, data) =>{ 
        if(wFileName.endsWith(".js")) {
            result = data;
        }
    };

    if (diagnostics != null) {
        diagnostics.push(...program.getSyntacticDiagnostics(sourceFile));
        diagnostics.push(...program.getSemanticDiagnostics(sourceFile));
        diagnostics.push(...program.getOptionsDiagnostics());
    }
    program.emit(sourceFile);
    return result;
}

Usage:

let diagnostics: typescript.Diagnostic[] = []
let result = transpileWithAllErrors(template, {}, undefined, diagnostics);
for (let err of diagnostics) console.log(err.messageText);
console.log(result);

Note: This method does module resolution relative to the current path so the script has access to any modules installed in the current path. Also I did not do extensive testing on the code, but it should work.

Upvotes: 2

Related Questions