【发布时间】:2021-05-13 15:01:37
【问题描述】:
我正在使用TypeScript Compiler API 中的TypeChecker,以便为我的程序的 AST 中的每个节点提取(推断)类型信息。特别是,我尝试从导入的模块函数中找出返回值,例如:
var vec3 = require('gl-matrix/vec3')
var myVec = vec3.fromValues(1, 2, 3) // $ExpectedType vec3
这适用于使用import { … } from '…' 语句导入的模块,但不幸的是,使用require() 导入的模块无法正确识别,我只收到any 类型。但是,我设置了两个编译器选项allowJs 和checkJs。
为什么require()d 模块的类型不能正确推断? VS Code(哪个 AFAIK 依赖相同的 API?)也能够从 require() 语句推断类型,所以我猜一般来说, tsc 能够处理它们。我需要以不同方式设置任何其他编译器选项吗?或者这确实不支持,我需要为此使用其他包?
这是一个最小的重现脚本,我也把它和两个示例文件放在 repl.it 上: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)
}
非常感谢您!
【问题讨论】:
-
你所做的一切对我来说似乎都是正确的。我认为编译器在解析模块
"gl-matrix/vec3"时遇到问题,因为它在执行require('gl-matrix').vec3时工作正常。语言服务确实从包中的 javascript 文件中解析了fromValues方法,这很有趣,以至于编译器 API 没有提供该方法……也许语言服务有一些特定的不同功能……我不知道。 -
谢谢大卫,我也注意到了这一点。 ???我在这里为 TypeScript 提交了一个问题:github.com/microsoft/TypeScript/issues/44077
标签: javascript typescript ecmascript-6 tsc typescript-compiler-api