如何查看TypeScript如何计算类型?


18

问题:我正在处理一个具有许多条件类型的文件,这些条件类型是从先前定义的条件类型派生其类型的,这已经变得非常复杂,并且很难调试如何派生类型。

我试图找到一种方法来“调试”或列出TypeScript编译器如何根据条件类型进行确定并选择一条路径来导出最终类型。

我已经浏览了编译器选项,但在该区域还没有找到任何东西...

我现在正在寻找的一个类比是,DEBUG=express:*如果您想查看快递服务器在做什么,可以使用一种设置类型。

但是,我要解决的实际问题是能够解构和调试如何在大型复杂的分层类型定义中派生类型。

重要说明:我不是要调试TypeScript项目的运行时执行。我正在尝试调试TypeScript编译器如何计算类型。


只需使用一个好的IDE,实例化您的类型并将鼠标悬停在编辑器中打开的源文件中的值上即可。通过使用该建议,您还有其他需要的信息吗?
帕特里克·罗伯茨

@PatrickRoberts-感谢您的答复。当我这样做时,它指向具有嵌套条件类型的复杂类型。反过来,这又指向了另一个类似的复杂类型,并且它继续运行,有时会以不明显的方式分支。尝试找出如何调试类型构造分支发生的原因。
盖伊,

1
我认为您的问题将从一个具体的例子中受益。我也遇到过您之前描述的情况,但是通常我发现解决方法涉及到重写类型,使它们更加不透明(例如interface具有自记录容器名称的通用名称,而不是type试图扩展其名称的通用名称)。在IDE的工具提示中进行定义)或仅重构源代码,以免完全过度使用复杂的条件类型。
帕特里克·罗伯茨

@PatrickRoberts试图将此仓库升级到Hapi / Joi @ 16并调试类型生成是导致此问题的原因。github.com/TCMiranda/joi-extract-type
Guy

@PatrickRoberts这是讨论升级本身的具体问题。github.com/TCMiranda/joi-extract-type/issues/22
Guy

Answers:


1

打字稿中没有任何内置机制可以注销所需的相关信息。但是,如果您想了解内部工作,这就是源代码中实际解决条件类型的地方。

看一下这些地方checker.ts

ln:13258 instantiateTypeWorker()
ln:12303 getConditionalType()
ln:12385 getTypeFromConditionalTypeNode()
ln:12772getTypeFromTypeNode()


附带的是我不小心将它们拼在一起的半成品打字稿插件。它注销了的原始数据结构ConditionalType。要了解此结构,请检查types.ts ln:4634。

这个插件的用户体验很糟糕,但是该结构确实告诉您typescript如何确定条件类型的最终值。

一些烦人的详细说明来使此插件运行:

  1. mkdir my-ts-plugin && cd my-ts-plugin
  2. touch package.json 和写 { "name": "my-ts-plugin", "main": "index.js" }
  3. yarn add typescript fast-safe-stringify
  4. 将此代码段复制粘贴到index.ts,使用tsc编译为index.js
  5. yarn link
  6. 现在cd到您自己的ts项目的目录,运行yarn link my-ts-plugin
  7. 添加{ "compilerOptions": { "plugins": [{ "name": "my-ts-plugin" }] } }到您的tsconfig.json
  8. 添加到工作区设置(.vscode/settings.json)此行:{ "typescript.tsdk": "<PATH_TO_YOUR_TS_PROJECT>/node_modules/typescript/lib" }
  9. 打开vscode命令面板并运行:
    1. TypeScript: Select TypeScript Version... -> Use Workspace Version
    2. TypeScript: Restart TS Server
    3. TypeScript: Open TS Server Log
  10. 您应该能够看到插件注销"PLUGIN UP AND RUNNING",现在打开ts代码文件并将鼠标悬停在某些条件类型节点上,您应该看到将loooooong json数据结构添加到了日志文件中。

感谢@hackape。我一直在研究它,并且可以生成一些有趣的日志,并且几乎列出了我在使用VSCode时以交互方式看到的内容,因此它不会比以前更吸引我了。有关如何使该插件正常工作的好的说明。
Guy

我把赏金给了你 即使还没有找到解决方案,我仍然认为通过在修改该插件方面付出更多的努力,我可能会到达那里,并且我无法想象在不久的将来会有更好的解决方案。感谢您的帮助和努力!
盖伊

1
@Guy感谢您的悬赏。因此,昨天我花了几个小时试图获得更多有用的结果。你是对的。上面的数据结构捕获了条件类型链的AST-ish对象,但这只是解析结果,而不是评估结果。至于类型解析器在评估时采取的“为什么”或条件分支,它需要转储所有中间步骤的结果,有点像将a debugger停在某个地方,然后手动查看调用堆栈中的局部作用域。
hackape

1
我修改了getConditionalType()in checker.ts来制作自定义构建打字稿,并插入了一些副作用逻辑以沿途转储中间信息。这次我得到了一些有用的东西。我将清理代码并稍后附加要点。
hackape

1
@Guy要点在这里
hackape
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.