typescriptabstract-syntax-treetypescript-compiler-api

How to serialize exported type using typescript compiler api


Hi I'm trying to get information on exported object type, to serialize it further. I checked there was similar question, and made the same example like that bellow:

const ts = require('typescript');

const code = `

type Config = {
  hello: string;
};

const config: Config = {
  hello: "world",
};

export default config;
`;

const sourceFile = ts.createSourceFile('myModule.ts', code, ts.ScriptTarget.ESNext);
const program = ts.createProgram([sourceFile.fileName], {});
const typeChecker = program.getTypeChecker();
const sourceFileSymbol = typeChecker.getSymbolAtLocation(sourceFile);
const exp = typeChecker.getExportsOfModule(sourceFileSymbol);

But it throws me an error, because for some reason sourceFileSymbol is undefined

typescript.js:49454 Uncaught TypeError: Cannot read properties of undefined (reading 'flags')
    at getSymbolLinks (typescript.js:49454:24)
    at getExportsOfModule (typescript.js:51578:25)
    at Object.getExportsOfModuleAsArray [as getExportsOfModule] (typescript.js:51517:35)
    at <anonymous>:18:27

I wish Typescript compiler api docs to be better I couldn't find anything valuable and I'm a bit lost here. Possibly the api has changed. I'm using version 4.7.1.


Solution

  • Check the output of:

    console.log(ts.getPreEmitDiagnostics(program));
    

    It's having trouble finding the source file:

    File 'myModule.ts' not found.
    

    Basically, the program being created is not using sourceFile and then searches for the myModule.ts on the file system. Getting it use an in-memory file system is a lot of setup and work with the compiler API. I'd recommend checking out something like @ts-morph/bootstrap to do that instead.


    // example using file system
    const program = ts.createProgram(["./myModule.ts"], {});
    console.log(ts.getPreEmitDiagnostics(program));
    const typeChecker = program.getTypeChecker();
    const sourceFile = program.getSourceFile("myModule.ts");
    const sourceFileSymbol = typeChecker.getSymbolAtLocation(sourceFile);
    const exp = typeChecker.getExportsOfModule(sourceFileSymbol);
    console.log(exp);