如何在Typescript-Transformer函数中正确转换'this'关键字?

问题描述

我创建了一个遍历AST并更改来自的数组调用的打字稿转换器

myArr.push(el)Array.prototype.push.call(myArr,args)

这适用于所有情况,除了数组在类内使用this关键字的情况下

this.myArr.push(el)转换为Array.prototype.push.call(this.myArr,args) 而正确的转换应为: this.myArr.push(el)Array.prototype.push.call(_this.myArr,args)_this已由ts-loader插件创建)

我该如何实现?

这是我的转换器的代码:

function getType(type) {
  if (type && type.symbol && type.symbol.name) {
    return type.symbol.name;
  } else if (
    type &&
    type.literalType &&
    type.literalType.symbol &&
    type.literalType.symbol.name
  ) {
    return type.literalType.symbol.name;
  }
  return null;
}
exports.__esModule = true;
const { ClassificationTypeNames } = require("typescript");
var ts = require("typescript");
var transformer = function (typechecker) {
  return function (context) {
    var visitor = function (node) {
      // 1. First check: chained expression
      // if it's array.filter().join().map() then I want to change only the first part
      // meaning 
      // if property access is a call expression - ignore and dont change
      if (
        ts.isCallExpression(node) &&
        ts.isPropertyAccessExpression(node.expression) &&
        ts.isCallExpression(node.expression.expression)

      ) {
        return ts.visitEachChild(node,visitor,context);
        
      }

      if (
        ts.isCallExpression(node) &&
        ts.isPropertyAccessExpression(node.expression)
      ) {
        const type = typechecker.getTypeAtLocation(node.expression.expression);
        const typeNameS = getType(type); 
        if (typeNameS === "Array") {
          const methodName = node.expression.name.getText();
          const callArgs = node.arguments;
          const identifier = node.expression.expression.getText();
          return ts.createCall(
            ts.createPropertyAccess(
              ts.createPropertyAccess(
                ts.createPropertyAccess(
                  ts.createIdentifier("Array"),ts.createIdentifier("prototype")
                ),ts.createIdentifier(methodName)
              ),ts.createIdentifier("call")
            ),undefined,[ts.createIdentifier(identifier),...callArgs]
          );
        }
      }

      return ts.visitEachChild(node,context);
    };
    return function (node) {
      return ts.visitNode(node,visitor);
    };
  };
};

解决方法

发现错误。

我正在获取标识符并手动创建。

const identifier = node.expression.expression.getText();

然后

ts.createIdentifier(identifier)

构造新节点的正确方法是将node.expression.expression直接传递给构造调用。

 return ts.createCall(
        ts.createPropertyAccess(
          ts.createPropertyAccess(
            ts.createPropertyAccess(
              ts.createIdentifier("Array"),ts.createIdentifier("prototype")
            ),ts.createIdentifier(methodName)
          ),ts.createIdentifier("call")
        ),undefined,[node.expression.expression,...callArgs]
      );

打字机引擎知道如何正确构建_thisthis引用。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...