How to use the TypeScript Compiler API to type-check modules imported using `require()`?

997 Views Asked by At

I am using TypeChecker from the TypeScript Compiler API in order to extract (inferred) type information for every node in the AST of my program. In particular, I try to find out the return values from imported module functions such as:

var vec3 = require('gl-matrix/vec3')
var myVec = vec3.fromValues(1, 2, 3) // $ExpectedType vec3

This works well for modules that were imported using the import { … } from '…' statement, but unfortunately, modules that were imported using require() like above are not recognized correctly, I only receive the type any for them. However, I have set both compiler options allowJs and checkJs.

Why are the types form require()d modules not inferred correctly? VS Code (which AFAIK relies on the same API?) is able to infer the types from require() statements as well, so I'd guess that in general, tsc is able of handling them. Are there any other compiler options that I need to set differently? Or is this indeed not supported and I need to use some other package for this?

Here is a minimum script to reproduce, I have also put it on repl.it together with two example files: https://replit.com/@LinqLover/typecheck-js

var ts = require("typescript")

// Run `node index.js sample-import.js`` to see the working TypeScript analysis
const files = process.argv[1] != "/run_dir/interp.js" ? process.argv.slice(2) : ["sample-require.js"]
console.log(`Analyzing ${files}:`)
const program = ts.createProgram(files, {
  target: ts.ScriptTarget.ES5,
  module: ts.ModuleKind.CommonJS,
  allowJs: true,
  checkJs: true
})
const checker = program.getTypeChecker()

for (const sourceFile of program.getSourceFiles()) {
  if (!sourceFile.isDeclarationFile) {
      ts.forEachChild(sourceFile, visit)
  }
}

function visit(node) {
  try {
    const type = checker.getTypeAtLocation(node)
    console.log(checker.typeToString(type))
  } catch (e) {
    // EAFP
  }
  ts.forEachChild(node, visit)
}

Thank you so much in advance!

1

There are 1 best solutions below

0
On BEST ANSWER

For follow-up, this turned out to be an issue with the type definitions for gl-matrix. I should better have tried out multiple packages before suspecting that the TypeScript engine itself could be broken ...

gl-matrix issue: https://github.com/toji/gl-matrix/issues/429