【问题标题】:TypeScript Compiler: TypeChecker#getTypeAtLocation() returns error for non-local typesTypeScript 编译器:TypeChecker#getTypeAtLocation() 为非本地类型返回错误
【发布时间】:2019-12-05 08:45:28
【问题描述】:

我正在开发一些 TypeScript 工具。为此,我使用TypeChecker#getTypeAtLocation() 来确定只有initializer 但没有声明typePropertyDeclaration 的类型。这适用于原语(数字、字符串等)和本地声明的类型。但是,对于导入的类型,我总是会得到一个错误类型。这在一定程度上是有道理的,因为导入的类型不是当前语法树的一部分,但在许多情况下它也没有帮助。可能是什么问题,请记住我使用 Nashorn 在 JVM 中运行 tsc.js

【问题讨论】:

  • ts.getPreEmitDiagnostics(program) 的结果是什么?
  • 我没有program,我只是使用ts.createSourceFile() 来获取语法树。
  • 那么您是如何获得typeChecker 的?它来自program.getTypeChecker()
  • 我刚刚打电话给ts.createTypeChecker();显然这还不够好,但没有文档...
  • 是的,这不是the public api 的一部分。

标签: typescript-compiler-api


【解决方案1】:

TypeChecker 实例只能与在创建类型检查器的相应 Program 实例中找到的源文件和后代节点一起使用。

您看到的错误类型是因为源文件尚未经历为其创建符号的绑定阶段。只有当类型检查器通过程序的CompilerHost 请求源文件时,才会对ts.SourceFile 进行绑定。

当调用TypeChecker#getTypeAtLocation 时,它可能会在内部尝试获取该节点的符号。当它这样做时,它不会找到符号然后返回错误类型。在提供字符串和数字文字时调用此方法有效,因为在这种情况下编译器不需要查看符号来确定类型。

要解决此问题,请从Program 实例(例如,使用program.getSourceFiles()program.getSourceFile(fileName))获取源文件,而不是ts.createSourceFile 的直接结果(仅将其提供给编译器主机)。

【讨论】:

  • 谢谢,信息量很大。那么使用包含所有相关 TypeScript 文件路径的 rootNames 调用 createProgram() 的想法是什么?
  • @FelixM 是的。或者足以让它根据提供的根名称的导入和导出来找出其他文件。
  • @DavidSherret 我在开发的 ts-loader 插件中遇到了同样的问题。在这种情况下,获取类型检查器是否有不同的方法?我通过在从插件传递给我的程序实例上调用 program.getTypeChecker() 来获取类型检查器。
猜你喜欢
  • 2017-03-05
  • 2019-08-21
  • 1970-01-01
  • 2016-05-06
  • 1970-01-01
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2018-08-12
相关资源
最近更新 更多