如何使用require('typescript')。转换?

时间:2018-01-26 04:02:04

标签: node.js typescript

create_table :documents do |t|
    t.string :title, null: false
end

create_table :related_documents do |t|
    t.integer :source_document_id, null: false
    t.integer :related_document_id, null: false
end

add_index :related_documents, [:source_document_id, :related_document_id], unique: true
add_foreign_key :related_documents, :documents, column: :source_document_id
add_foreign_key :related_documents, :documents, column: :related_document_id

class Document < ActiveRecord::Base
    # We have many document relationships where this document is the source document
    has_many :related_documents, foreign_key: :source_document_id

    validates :title,
        presence: true
end

class RelatedDocument < ActiveRecord::Base
    after_create :add_reciprocal_relationship
    after_destroy :remove_reciprocal_relationship

    belongs_to :source_document, class_name: Document
    belongs_to :related_document, class_name: Document

    validates :source_document,
        presence: true

    validates :related_document,
        presence: true,
        uniqueness: {
            scope: :source_document
        }

    private

    # Creates a reciprocal relationship
    def add_reciprocal_relationship
        RelatedDocument.find_or_create_by(
            related_document: self.source_document,
            source_document: self.related_document
        )
    end

    # Safely removes a reciprocal relationship if it exists
    def remove_reciprocal_relationship
        RelatedDocument.find_by(
            related_document: self.source_document,
            source_document: self.related_document
        )&.destroy
    end
end

如何在上面的操作中转换字符串?

1 个答案:

答案 0 :(得分:1)

您可以使用transpile功能。这将允许您编译任意字符串:

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);

修改

上面的解决方案有效,但它只检查语法错误而不是语义错误。执行模块解析并将检查语义错误的版本是:

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;
}

用法:

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

注意:此方法执行相对于当前路径的模块分辨率,以便脚本可以访问当前路径中安装的任何模块。此外,我没有对代码进行大量测试,但它应该可以工作。