【问题标题】:why getParentWhileKind in ts-morph not returns the expected parent of child?为什么 ts-morph 中的 getParentWhileKind 不返回孩子的预期父母?
【发布时间】:2022-12-03 01:45:08
【问题描述】:
我使用 ts-morph 分析我的代码,我想从 Identifier 位置获取父级 CallExpression。
所以我使用.getParentWhileKind(SyntaxKind.CallExpression),但函数返回null。
为什么?我有 CallExpression,它是 Identifier (foo) 的父级
我错过了什么?以及如何解决? (除了使用getParent().getParent()..)
import { Identifier, Project, SyntaxKind } from "ts-morph";
console.clear();
const project = new Project();
const sourceFile = project.createSourceFile(
"test.ts",
`
const fn = () => {
chain.foo.bar('arg');
}
`
);
const a = sourceFile.getDescendants().find((d) => d.getText() === "foo");
console.log({ a: a?.getParentWhileKind(SyntaxKind.CallExpression) });
codesandbox.io
【问题讨论】:
标签:
typescript
abstract-syntax-tree
ts-morph
【解决方案1】:
getParentWhileKind 的工作方式与此略有不同。从文档:
当父节点是指定的语法种类时,向上移动节点的父节点(祖先)。如果初始父级不是指定的语法类型,则返回 undefined。
由于 foo 的直接父级不是调用表达式,因此它只是返回未定义。我建议使用getParentWhile 来检查每个祖先,直到找到第一个CallExpression。
const parent = a?.getParentWhile((node) => {
if (node.isKind(SyntaxKind.CallExpression)) {
return false;
}
return true;
});
这有点违反直觉,因为当您找到所需的节点时,您会返回 false。但是返回 false 基本上告诉 ts-morph 我们已经完成查找。
【解决方案2】:
您可以使用template values ?Putout 代码转换器,我正在努力。
因此,如果您想从表达式中删除 foo:
chain.foo.bar('arg');
具有:
chain.bar('arg');
你可以使用something like:
// https://git.io/JqcMn
export const report = () => `Drop 'foo'`;
export const replace = () => ({
'__a.foo.__b(__c)': '__a.__b(__c)',
});
您可以以任何方式使用链接值 __a、__b 和 __c 进行操作。