我想使用自定义打字机转换器对一个特定的类进行以下转换。函数helper.isTargetClass(node)
例如可以是转换正确类的实用方法。但是,这种逻辑实际上并不是问题的一部分。
if (ts.isClassDeclaration(node) && helper.isTargetClass(node) {
/**
* 1)
* I would like to add a child to the class declaration.
* Specifically I would like to add a static property.
* E.g. public static instances = [];
*/
/**
* 2)
* I would like to add a constructor if there is none defined
*/
/**
* 3)
* I would like to insert the following line in the constructor block.
* this.instances.push(this);
*/
/**
* 4)
* I would like to to something for each method declaration.
* Specifically on ts.isMethodDeclaration(node)
* The use case does not matter.
* But e.g. changing...
*
* public greet(): string {
* return "Hello";
* }
*
* ... to public greet = jasmine.createSpy();
*/
/**
* 5)
* I would like to do something on property declaration.
* Specifically on ts.isPropertyDeclaration(node)
* The use case does not matter.
* But e.g. changing public myNumber = 7; to public myNumber = "7";
*/
}
我写了一个小辅助函数来遍历类声明节点的子级。
export function doForEachChild(node: ts.Node, context: ts.TransformationContext, callback: (node: ts.Node) => ts.VisitResult<ts.Node>): ts.VisitResult<ts.Node> {
const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult<ts.Node> => {
return callback(node);
};
return ts.visitEachChild(node, visitor, context);
}
它可以这样使用:
return doForEachChild(node, context, (childNode) => {
if (ts.isConstructorDeclaration(node)) {}
if (ts.isMethodDeclaration(node)) {}
if (ts.isPropertyDeclaration(node)) {}
});
我介绍了这个小助手,以便能够使用访客模式并修改特定的子节点。
我知道我可以像这样在类声明中添加一些内容:
const extendedMembers = ts.createNodeArray([createInstancesProperty(symbol.name), ...node.members]);
return ts.createClassDeclaration(node.decorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses, extendedMembers);
但是我不知道如何组合呈现的内容。
因此,我想问一问是否有人对此有任何想法或经验?是否有一种好的方法可以完成所有期望的任务?如果要插入子节点,是否可以使用访客模式?我的小帮手有道理还是有更好的方法来解决这个问题?
此问题(https://github.com/madou/typescript-transformer-handbook/issues/12)处理的问题基本上相同。如果我的问题仍然不清楚,可能会有所帮助。
在此问题中,有人提出以下建议:
通常,您基本上希望通过消除过程来做到这一点,直到到达您真正想要更改的节点为止,所以我可能要在if语句中包含一些要更改的内容
就我而言,我真的不想更改某些东西;我想插入一些东西。所以呀的确,将要更改的节点将是类声明。我已经包含了如何实现此功能的代码段。但是我不知道如何修改其他东西/完成其他任务。有点难以解释。但是无论如何仅修改节点(没有访问者模式并返回VisitorResult)将无法解决问题。至少到目前为止我的经历。
因此,主要问题是将子节点插入类声明并修改其他特定的子节点的组合。
任何建议,我将不胜感激。预先感谢。