Search code examples
typescripttypescript-compiler-api

Generating type declaration from import url using the TypeScript compiler API


I'm trying to generate some type declarations for a project. The main idea here is that I got to a point where I am able to generate something like this:

type T = typeof import("somepath").default

Where default is a function.

The code that does this is:

ts.createTypeAliasDeclaration(
  undefined,
  undefined,
  ts.createIdentifier("T"),
  undefined,
  ts.createTypeOf(
    ts.createPropertyAccess(
      ts.createCall(
        ts.createToken(ts.SyntaxKind.ImportKeyword),
        undefined,
        [ts.createStringLiteral("somepath")]
      ), 
      ts.createIdentifier("default"))
    ),
    undefined,
    true
);

After printing that to the console I can see the output of that is indeed:

type T = typeof import("somepath").default

Now I have a variable, say t that holds the node of that type alias declaration, but when I try to extract the type with the type checker I keep getting any. So far I've tried checker.getTypeAtLocation and checker.getTypeFromTypeNode but I keep getting any no matter what I try (I checked manually and vscode can indeed verify the type is not any).

Any help would be much appreciated, Thanks!


Solution

  • The TypeScript compiler was designed to do type checking before transformation and so for the most part the type checker assumes the node it's type checking will be contained in a source file node and that the source file's text will match the descendant AST nodes (there's some internal data that gets set on nodes when parsing text to a source file).

    You can make this work by printing out the node to text (using ts.createPrinter), reparsing it in a source file (ts.createSourceFile... or updating an existing source file with the update method), getting a reference to the parsed T type alias node, then using that source file in a new program to get a new type checker. It's a lot of code, so it would be too much work to post it here.