I got interface names in my code by using compiler API inside typescript sub-project. typescript version 4.1.3
Here is my promise function:
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);
});
}
EDIT
Above function didn't cover importing types from other files, which means that any interface file having imports from somewhere, failed.
To make those to work, you may want to configure the createProgram params to match your project. Here some advices (NodeJS Project):
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);
Then modify above function to use the created program with configs.