How to clone or detach node from the source using ts-morph?

198 Views Asked by At

I want to clone or detach node from typescript ast (using ts-morph).

I explain what I mean using this example:

I have two projects:

const fooProject = new Project();
const barProject = new Project();

const fooSourceFile = fooProject.createSourceFile(
  "foo.ts",
  `
  const fn = [{ id: 1 }, { id: 2 }, { id: 3, children: [{ id: 4 }] }];
`
);

const barSourceFile = fooProject.createSourceFile("bar.ts", ``);

And the goal is to increment each id by one and then add it to barSourceFile and not change the fooSourceFile.

But here is the problem, I must call saveSync in the end of my application and I can't change that:

fooProject.saveSync();
barProject.saveSync();

So it easier for me to find the correct node and change the values and write to the target source file as I do here:


const vars = fooSourceFile.getDescendantsOfKind(SyntaxKind.VariableDeclaration);
vars.forEach((v) => {
  // v.forget();
  // v.forgetDescendants();

  const props = v
    .getDescendantsOfKind(SyntaxKind.Identifier)
    .filter((i) => i.getText() === "id");

  props.forEach((prop) => {
    const propertyAssignment = prop.getParentIfKind(
      SyntaxKind.PropertyAssignment
    );

    const oldValue = propertyAssignment?.getInitializer()?.getText();
    const newValue = +(oldValue as string) + 1;
    console.log({ newValue });

    propertyAssignment?.setInitializer(newValue.toString());
  });

  console.log({ props: props.map((p) => p.getText()) });
});

barSourceFile.addStatements(vars.map((a) => a.getText()));

I tried to use forgot and forgetDescendants methods, but it didn't work because I got an error saying the node was forgotten or removed, so I couldn't change the values or take any action.

If it is possible to clone the node or make changes that are not affected on the node - this is what I am looking for.

Is it possible to do with ts-morph?

codesandbox

0

There are 0 best solutions below