0

I'd like to extract metadata related to Props objects. For the example below I might get something as simple as this:

{
  suffix: 'string',
  count: 'number',
  increment: 'function'
}

I realize that this is a complex task, as each of those props could be union types for example. But I'd like a starting point, and I can live with not capturing the entire type info into this reflection.

The manual approach would be to use a parser to get the AST of that Props object, but this involves a serious degree of work because any of those types could reference types from other files, so I'd have to write a script that essentially knows how to follow imports, and possibly other complications I haven't thought of yet.

Before I embark into such a complicated task, I was wondering if there is already some API to do this, whether TypeScript official or made and used by some other popular tool. Code editor plugins must get this information somehow to provide autocomplete.

enter image description here

So far I found this project: https://github.com/plumier/tinspector – But it doesn't seem very used and it doesn't seem to follow imports either, which is my main concern.

Thanks!

treznik
  • 7,955
  • 13
  • 47
  • 59
  • OK, it's important to keep in mind that *there is no type system at runtime*. It's impossible to extract the TS types when this code runs because those types are gone. You can get the *current type* of each property but it would be rather basic - if you have, for example `myProp: number | string` you can only see what the current value if `myProp` is, so if it currently holds a number, there is no way to know it would could also hold a string. Similarly, if the value is `null` or `undefined`, then you can't even guess what the type would be otherwise. – VLAZ Feb 04 '20 at 13:02
  • I didn't mean at runtime. I'd like to statically extract this information on the backend, where I also have access to the file system. – treznik Feb 04 '20 at 13:06
  • Well, you had your `function x(props: Props)` which seems like it would be executed at runtime. – VLAZ Feb 04 '20 at 13:11
  • That was just an example of how code editors have this information. Sorry for the confusion. – treznik Feb 04 '20 at 13:15

1 Answers1

1

You can use the TypeScript compiler (which is available as an NPM package) to do statical analysis of TypeScript source code.

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

/** Root of AST for complete program/file */
const ast = ts.createSourceFile(
  'source-file.ts',
  fs.readFileSync(`${process.cwd()}/src/source-file.ts`).toString(),
  ts.ScriptTarget.ES2018,
  true
);

For your specific scenario you would need to look into the TypeScript compiler API, but in general you traverse the AST and check for various types of nodes that you would like to process in your application, like interfaces for instance.

switch (node.kind) {
  case ts.SyntaxKind.InterfaceDeclaration:
    // Process interface declaration node by going deeper in another function
    break;
  // And so on...
}

Like you said, depending on what you want to do it may be more or less complicated. But the compiler API is fairly easy to work with from your NodeJS-backend.

Greg
  • 313
  • 3
  • 8