如何在TypeScript Transformer API中终止visitEachChild的遍历?
如何终止TypeScript visitEachChild的子节点遍历?
当使用visitEachChild遍历父节点的子节点时,若想实现类似break的终止效果(比如只遍历到指定子节点就停止,不再处理后续节点),可以参考以下方案:
举个例子,我们有如下类结构,需要遍历到template方法就终止,不再处理后续的someThing和foo方法:
class A { public template() { // <-- 仅需遍历到此处 return 'Template'; } someThing() {} foo() {} }
问题分析
ts.visitEachChild的设计逻辑是遍历所有子节点,无法直接中断遍历流程。因此要实现终止效果,必须手动遍历子节点,替代visitEachChild的调用。
解决方案1:仅终止遍历,不修改节点
如果只是需要停止遍历,不需要修改节点结构,可以直接手动循环子节点,找到目标后break:
const transformerFactory: ts.TransformerFactory<ts.Node> = (context: ts.TransformationContext) => (rootNode) => { const visit = (node: ts.Node): ts.Node => { if (ts.isClassDeclaration(node)) { // 手动遍历类的子节点,替代visitEachChild for (const child of node.getChildren(context)) { if (ts.isMethodDeclaration(child)) { console.log(child.name.getText()); if (child.name.getText() === 'template') { // 找到目标节点,终止遍历 break; } } } return node; } return ts.visitEachChild(node, visit, context); }; return ts.visitNode(rootNode, visit); };
解决方案2:终止遍历并修改节点结构
如果需要在终止遍历的同时,保留遍历到终止点前的节点并生成新的类声明,可以这样实现:
const transformerFactory: ts.TransformerFactory<ts.Node> = (context: ts.TransformationContext) => (rootNode) => { const visit = (node: ts.Node): ts.Node => { if (ts.isClassDeclaration(node)) { const newClassElements: ts.ClassElement[] = []; let stopTraversal = false; // 遍历类的所有子节点,过滤出类元素(方法、属性等) for (const child of node.getChildren(context)) { if (stopTraversal) break; if (ts.isClassElement(child)) { if (ts.isMethodDeclaration(child)) { console.log(child.name.getText()); if (child.name.getText() === 'template') { // 添加当前节点到新列表,标记停止遍历 newClassElements.push(child); stopTraversal = true; } else { newClassElements.push(child); } } else { // 非方法类元素直接保留 newClassElements.push(child); } } } // 生成新的类声明,仅包含终止点前的元素 return ts.factory.updateClassDeclaration( node, node.modifiers, node.name, node.typeParameters, node.heritageClauses, newClassElements ); } return ts.visitEachChild(node, visit, context); }; return ts.visitNode(rootNode, visit); };
内容的提问来源于stack exchange,提问作者Grizzly
相关产品推荐
相关产品推荐

