使用不同的类方法,具体取决于所使用的目标编译器选项

时间:2019-07-26 04:27:21

标签: javascript typescript class

如何根据target文件中使用的tsconfig.json选项,告诉TypeScript使用不同编写的方法(在同一类上)?

我目前正在将我的一个脚本重写为TypeScript以“管理”一个源,因为目前我正在处理彼此相邻的ES5和ES6文件。由于TypeScript支持仅更改tsconfig.json文件中的输出目标,所以我只需要一个版本即可更新和维护。

问题是我正在使用ES6版本的生成器,从理论上讲这不是问题,因为TypeScript将伪生成器“添加”到了我的ES5文件的顶部。但是:我目前在ES5文件上使用的伪生成器代码“更干净”,并且代码更少。

问题

是否可以覆盖相应的“生成器”方法或使用任何特殊的注释批注(例如//@ts-target)来告知编译器应根据使用的{{1}使用哪个代码(函数体) }中的配置文件? (即使我在官方文档中找不到这样的解决方案)。

我想,可以添加到TypeScript编译器过程中的其他函数或脚本也将有所帮助,因为我正在使用一个小的node.js脚本(它们在不更改{{1 }}文件。)

或者是否存在某种扩展,可以将同一类的不同方法移动到不同文件中?这样,我可以“提取”相应的“生成器”方法,但这会引起另一个问题:如何根据目标链接它们,因为我在主脚本文件上使用target链接来获取所有内容在一起。

还有其他想法吗?

tsconfig.json

当前,我的脚本的ES5版本中添加了伪生成器代码。我想通过与我自己的伪生成器一起使用不同的方法/函数主体来防止这种情况。因此,我需要告诉TypeScript,他应该“忽略” ES6中的伪生成器/ ES5中的真实生成器,并根据使用的/// <reference />选项仅渲染其中之一。

1 个答案:

答案 0 :(得分:0)

这有点棘手,但是感谢this GitHub issue,我找到了解决方案。

如上所述,我使用自己的node.js脚本将TypeScript文件编译为两个不同的JavaScript版本(ES5和ES6)。因此,我将TypeScript API与ts.createProgram方法一起使用。此方法允许添加一个主机对象作为第三个参数,该对象将接管一些编译器进程,其中一个是称为getSourceFile的文件加载器。

然后剩下的事情就相对容易了:搜索自定义注释注释(在我的情况下分别为\\\@ts-target:ES5\\\@ts-target:ES6)并使用RegExp对其进行过滤。也许不是最好的解决方案,但它可行!

function compileTS(){
    let config = readConfig("ts/tsconfig.json");
    let host = ts.createCompilerHost(config.options);
    let sourceFile = host.getSourceFile;

    // ES5 JavaScript
    (function(config){
        host.getSourceFile = function(filename) {
            if(filename === "ts/options.ts"){
                let file = fs.readFileSync("./ts/options.ts").toString();
                file = file.replace(/[ ]+\/\/\/\@ts\-target\:ES6\s+([\s\S]*)\/\/\/\@ts\-target\:ES6/gm, "");
                return ts.createSourceFile(filename, file, ts.ScriptTarget.ES5, true);
            }
            return sourceFile.call(host, filename);
        }
        let program = ts.createProgram(config.fileNames, config.options, host);
        let emitResult = program.emit();
        report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
        if(emitResult.emitSkipped){
            process.exit(1);
        }
    }(config));

    // ES6 JavaScript
    config.options.target = 2;
    config.options.outFile = "../dist/js/tail.select-es6.js";
    (function(config){
        host.getSourceFile = function(filename) {
            if(filename === "ts/options.ts"){
                let file = fs.readFileSync("./ts/options.ts").toString();
                file = file.replace(/[ ]+\/\/\/\@ts\-target\:ES5\s+([\s\S]*)\/\/\/\@ts\-target\:ES5/gm, "");
                return ts.createSourceFile(filename, file, ts.ScriptTarget.ES2015, true);
            }
            return sourceFile.call(host, filename);
        }
        let program = ts.createProgram(config.fileNames, config.options, host);
        let emitResult = program.emit();
        report(ts.getPreEmitDiagnostics(program).concat(emitResult.diagnostics));
        if(emitResult.emitSkipped){
            process.exit(1);
        }
    }(config));
}