2

I want to get all interfaces names from a specific file.

for example:

file1.ts

   private interface first{
...
}

private interface second{
...
}

private interface third{
...
}

file2.ts

const interfacesList = GetInterfacesFrom(filePath); //in this case filePath = file1.ts

I whould expected to return: ["first","second","third"];

UPDATE

I want to build a mechanism like EntityFramework in typescript;

But I need to know how to match automatically the name of interfaces/classes with api path, to know if I have a interface or class which api to call...

Alex
  • 1,013
  • 1
  • 13
  • 27
  • 2
    You can't do that in a regular script because interfaces aren't being compiled into javascript equivalent, so at runtime there are no interfaces. You can probably use the [Compiler API](https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API) – Nitzan Tomer Mar 08 '17 at 13:51
  • The normal way to do this is with exports so I find the proposed code above highly unorthodox. You might have a requirement that is not obvious. If you tell us more details of what you're attempting to do, people can probably steer you in the right direction. Like Nitzan Tomer said, those, Interfaces are not part of the final JS code, so you can't introspect about them in at runtime. – zeh Mar 08 '17 at 16:37

2 Answers2

2

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.

Polpo
  • 85
  • 6
0

You need to use the compiler API

The API allows you to parse source code and get symbols from it.

basarat
  • 261,912
  • 58
  • 460
  • 511