【发布时间】:2020-05-07 07:57:54
【问题描述】:
给定:
// foo.ts
import { bar } from "./bar"
// bar.ts
export const bar = 3;
如果我在“foo.ts”中有bar 的ts.Symbol,我如何才能访问“bar.ts”中的bar?
理想情况下,TS 编译器 API 会公开一个定义使用链,我可以遍历该链来查找定义。不过,我认为不会。
所以现在我正在尝试:
- 使用模块说明符“./bar.ts”和当前的
ts.SourceFile获取代表“bar.ts”的ts.ResolvedModule对象,其中包含完整的文件路径。 -
ts.SourceFile(fullFilePath)为“bar.ts”获取ts.SourceFile - 执行
checker.getExportsOfModule(symbolForBarDotTs)以从“bar.ts”获取导出并找到具有匹配名称的导出。
棘手的部分似乎是从模块说明符中解析模块。我不想从头开始编写模块解析的逻辑,因为算法很复杂,并且依赖于至少六个编译器选项的交互。 TS Compiler API 的两个部分看起来很有希望:
-
host.resolveModuleNames,不幸的是只有宿主实现了它才可用,而默认编译器宿主没有实现它。 - 使用
(program.getSourceFile(pathToFoo) as any).resolvedModules。resolvedModules属性似乎完全符合我的要求,但不是公共 API 的一部分。
有没有更好的方法?我希望:
- 停止使用非私有 API
-
不要做太多编译器已经知道该怎么做的工作
“bar.ts”
在这种情况下,很容易看到“./bar”指的是文件系统上具有匹配名称的相邻源文件,但是当有人使用“paths”或“node_modules”或“@types”时,等等然后模块解析是不平凡的。
更新
一般问题:
如果我在“foo.ts”中有
bar的ts.Symbol,我如何才能访问“bar.ts”中的bar?
@DavidSherret's answer 大部分时间都可以工作。
但是,在以下情况下,它并不能满足我的要求:
// foo.ts
import { bar } from "./bar"
// bar.ts
export { bar } from "./baz"
// baz.ts
export const bar = 3;
TypeChecker#getAliasedSymbol 表示“foo.ts”中的baz 指向“baz.ts”中的bar,完全跳过“bar.ts”。这对我的目的不起作用,因为我试图找出一组入口点,不再需要 .d.ts 文件的哪些部分,并删除不需要的部分。在这种情况下,删除“bar.ts”是个坏主意。
【问题讨论】:
-
你问这么简单的问题:P。对于编译器 API 的东西,GH 不是更好的场所吗?
-
谢谢!我不确定我是否会将其称为功能请求,除非有人确认我想要实现的目标没有公共 API,然后我可以打开一个问题。
-
如果我没记错的话,你可以在 GitHub 上用问题打开一个问题。 @TitianCernicova-Dragomir 是贡献者之一...
-
@HereticMonkey Max Heiber 也是贡献者 :)
-
打开了一个问题:感谢您的反馈和建议github.com/microsoft/TypeScript/issues/36351
标签: typescript typescript-compiler-api