通过在 typescript 子项目中使用编译器 API,我在代码中获得了接口名称。打字稿版本 4.1.3
这是我的承诺功能:
const getInterfacesNamesFromFile = (filepath: string): Promise<string[]> => {
return new Promise ((res, rej) => {
// absolute path to interface file
const absoluteFilepath = path.join(path.resolve(...basePath), filepath);
const mainProgramFilepath = path.join(__dirname, '../', '../', 'src', 'main.ts');
let program = ts.createProgram([mainProgramFilepath], {allowJs: true});
const sourceFile = program.getSourceFile(absoluteFilepath);
const interfaceNames: string[] = [];
ts.forEachChild(sourceFile, node => {
if (ts.isInterfaceDeclaration(node) {
interfaceNames.push(node.name.text);
}
})
res(interfaceNames);
});
}
编辑
上面的函数没有涵盖从其他文件导入类型,这意味着任何从某个地方导入的接口文件都失败了。
为了使这些工作,您可能需要配置 createProgram 参数以匹配您的项目。这里有一些建议(NodeJS 项目):
import path from 'path';
import dir from 'node-dir';
import * as ts from 'typescript';
// compiler options has enums, so check definitions inside
const tsconfig: ts.CompilerOptions = {
moduleResolution: 2, // "node"
module: 1, // CommonJS
esModuleInterop: true,
target: 2, // ES6, says ES2015, should be same
baseUrl: "../src", // .. if you have typescript subproject
...
}
// get source files in array, same as tsconfig includes: ['src/**/*']
const rootNames = await new Promise((res, rej) => {
dir.files(path.resolve('src'), (err, files) => {
err ? rej() : res(files);
});
});
let program = ts.createProgram(rootNames, tsconfig);
然后修改上述函数以使用带有配置的创建程序。