typescript - 运行 Typescript 编译器插件/转换器后的类型检查
问题描述
我正在关注关于如何编写 Typescript 编译器插件/转换器的博客 ( https://dev.doctorevidence.com/how-to-write-a-typescript-transform-plugin-fc5308fdd943 )。
在应用第一个应该引入类型错误的简单转换(在没有该属性的对象上访问的某些属性)之后,我注意到没有显示类型错误。事实上,编译器照常进行。
import * as ts from "typescript";
export const transformerFactory = (
program: ts.Program
): ts.TransformerFactory<ts.SourceFile> => {
return (context: ts.TransformationContext): ts.Transformer<ts.SourceFile> => {
const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
if (node.expression.escapedText === "someCall") {
return ts.createCall(
ts.createPropertyAccess(node.expression, "nonExisting"),
node.typeArguments,
node.arguments
);
}
}
return ts.visitEachChild(node, visitor, context);
};
return (sf: ts.SourceFile) => ts.visitNode(sf, visitor);
};
};
适用于index.ts
:
declare function someCall(...args: any[]): string;
console.log(someCall(1, 2, true));
产量index.js
:
console.log(someCall.nonExisting(1, 2, true));
(即使有noEmitOnError: true
)
这是预期的行为吗?这是我可以在某处启用的东西吗?
解决方案
这是预期的行为吗?
是的。
这是我可以在某处启用的东西吗?
不,变压器的用途有限。不支持编译器的通用通用“插件”。
Transformers 作为“发射”阶段的一部分运行,该阶段从经过类型检查的 AST 生成 javascript 代码。
变形金刚公关中的这条评论说
转换,所有这些都发生在检查阶段发生之后
更新
有什么方法可以编译两次:一次转换文件,一次对整个内容进行类型检查?我不介意是否必须对转换后的文件进行单独检查。
我不知道。首先要尝试让您的转换器像以前一样修改 AST,然后通过调用手动检查修改后的文件
program.getDiagnosticsProducingTypeChecker().getDiagnostics(sourceFile)
(getDiagnostics
有第二个参数 - cancellationToken
- 但似乎省略它是安全的,因为它总是检查是否undefined
在类型检查器代码中。通常,您可以查看各种编译器 API 如何在其自己的源代码中使用,例如emit
类型 -首先通过调用各种检查program.getNNNDiagnostics
,然后使用变换运行发射器。)
这可能会或可能不会起作用,因为类型检查器会修改 AST,并且它取决于 AST 是否处于正确状态。
然后,您可能想查看构建器 API - 它的目的是监视源文件修改并重新编译更改的文件(源代码链接)。我不知道在 AST 修改上重新编译它有多难,而且看起来你将无法使用转换器中可用的访问者;您必须手动遍历 AST。
此外,还有ts-simple-ast库,其既定目的是“提供一种简单的方法来导航和操作 TypeScript 和 JavaScript 代码”。我自己没有使用过它,也不知道它对你的目标有多大用处。
推荐阅读
- excel - 获取运行时错误 13-VBA excel 宏
- php - 我无法在 xampp 中打开我的 phpmyadmin。它显示访问被拒绝
- reactjs - 酶 - TS2350:只能使用 'new' 关键字调用 void 函数
- gcc - 将 objcopy 与“精简存档”文件一起使用时出现问题
- python - 尽管满足条件,但循环没有结束
- r - R 使用 purrr::map 将函数应用于数据框列表中的选定列
- php - 使用 writeHTML 在 TCPDF 中获取间距问题
- javascript - 使用javascript将图像添加到选择中的选项
- python - 为什么我在 Panel 中得到一个空的输出对象?
- msbuild - 用于多个框架的 Nuget 包