【发布时间】:2020-09-18 10:47:26
【问题描述】:
让我们来看看打字稿文件:
class A {
private x? = 0;
private y? = 0;
f() {
console.log(this.x, this.y);
delete this.x;
}
}
const a = new A();
a.f();
我正在使用 awesome-typescript-loader 在 webpack 中构建它:
{
test: /\.tsx?$/,
include: path.resolve("./src"),
exclude: path.resolve("./node_modules/"),
use: {
loader: 'awesome-typescript-loader',
options: {
getCustomTransformers: program => ({
before: [deleteTransformer(program)]
})
}
}
},
deleteTransformer 是我自己的转换器,它用delete this.y 替换任何delete 表达式:
import * as ts from "typescript";
export default function getCustomTransformers(program: ts.Program): ts.TransformerFactory<ts.SourceFile> {
return (context: ts.TransformationContext) => (file: ts.SourceFile) => visitNodeAndChildren(file, program, context);
}
function visitNodeAndChildren<N extends ts.Node>(node: N, program: ts.Program, context: ts.TransformationContext): N {
return ts.visitEachChild(visitNode(node, program), childNode => visitNodeAndChildren(childNode, program, context), context);
}
function visitNode<N extends ts.Node>(node: N, program: ts.Program): N {
if (ts.isDeleteExpression(node)) {
return ts.factory.createDeleteExpression(ts.factory.createPropertyAccessExpression(
ts.factory.createThis(),
"y",
)) as ts.Node as N;
}
return node;
}
如果我运行编译,我会得到我期望的代码(删除 y,而不是 x):
/***/ "/7QA":
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var A = /** @class */ (function () {
function A() {
this.x = 0;
this.y = 0;
}
A.prototype.f = function () {
console.log(this.x, this.y);
delete this.y;
};
return A;
}());
var a = new A();
a.f();
/***/ }),
但是,如果我将名称 y 更改为 z,这在 A 类中不存在,我将不会收到任何错误消息。
另外,如果我将类 A 更改为具有非可选的 x 并将 y 保留在转换器中,我会收到一个错误
× 「atl」: Checking finished with 1 errors
ERROR in [at-loader] ./src/index.ts:7:16
TS2790: The operand of a 'delete' operator must be optional.
根据这些事实,我了解到 在实际检查代码后应用了转换器,但转换器包含在 before 部分中,因此我希望 typescript 验证生成的代码而不是原始代码。
为什么会这样? getCustomTransformers 对象中的before 和after 变压器有什么区别(我都试过了,没有发现区别)?以及如何在检查代码之前应用转换?
【问题讨论】:
标签: typescript abstract-syntax-tree typescript-compiler-api awesome-typescript-loader