在自定义LanguageServiceHost中引用.d.ts文件

时间:2017-02-08 22:12:50

标签: typescript

我正在实现一个非常频繁地调用的Typescript编译器,需要快速编译单个Typescript文件。我已按照本指南设置内存编译器:http://blog.scottlogic.com/2015/01/20/typescript-compiler-api.html。 我正在编译的TS文件有几个导入,比如jQuery,我有TSD文件。

typescriptCompile.ts

import * as fs from 'fs';
import * as path from 'path';
import * as ts from 'typescript';

class MyLanguageServiceHost implements ts.LanguageServiceHost {
    files: { [fileName: string]: { file: ts.IScriptSnapshot; ver: number } } = {};

    log = _ => { };
    trace = _ => { };
    error = _ => { };
    getCompilationSettings = ts.getDefaultCompilerOptions;
    getScriptIsOpen = _ => true;
    getCurrentDirectory = () => "";
    getDefaultLibFileName = _ => "lib";

    getScriptVersion = fileName => this.files[fileName].ver.toString();
    getScriptSnapshot = fileName => this.files[fileName].file;

    getScriptFileNames(): string[] {
        var names: string[] = [];
        for (var name in this.files) {
            if (this.files.hasOwnProperty(name)) {
                names.push(name);
            }
        }
        return names;
    }

    addFile(fileName: string, body: string) {
        var snap = ts.ScriptSnapshot.fromString(body);
        snap.getChangeRange = _ => undefined;
        var existing = this.files[fileName];
        if (existing) {
            this.files[fileName].ver++;
            this.files[fileName].file = snap
        } else {
            this.files[fileName] = { ver: 1, file: snap };
        }
    }
}

var host = new MyLanguageServiceHost();
var languageService = ts.createLanguageService(host, ts.createDocumentRegistry());

const includeFiles = [
    'es6-promise.d.ts',
    'jquery-3.1.1.d.ts',
    'twemoji-2.2.4.d.ts'
];

includeFiles.forEach(file => host.addFile('types/' + file, fs.readFileSync(path.join(__dirname, 'types', file)).toString()));

export function compile(code: string) {
    host.addFile(`code.ts`, code);

    var output = languageService.getEmitOutput("code.ts").outputFiles[0].text;

    console.log(output);
}

编译代码

import * as twemoji from 'twemoji-2.2.4';

export const test = twemoji.parse('test');

语言服务尝试访问脚本twemoji-2.2.4.ts而不是twemoji-2.2.4.ts时会出错。如何使用语言服务/编译器注册定义?

1 个答案:

答案 0 :(得分:0)

我已经部分找到了一个足以涵盖我的用例的答案。我已将以下内容添加到MyLanguageServiceHost

resolveModuleNames = (moduleNames: string[], containingFile: string): ts.ResolvedModule[] => {
    return moduleNames.map(name => {
        return {
            resolvedFileName: name + '.d.ts',
        }
    });
};

这会将所有模块解析为.d.ts形式,这就是我所需要的。如果您有定义和源文件的混合,我仍然不确定如何处理它。