I am currently trying to resolve the "definition" of "Identifier".
Note that I am using the ts-morph library.
As an example, given the following source:
const fn = () => {}
const fn2 = fn.bind(this);
I want to get the "definition" of fn Identifier (in the second line).
ts-morph is able to use "getDefinitionNodes" to get the actual fn function, but it does only to nodes with the type of Identifier and on the correct node.
So here I found the bind Identifier (from there I want to start).
Now I need to find the fn (it also can be this.fn sometimes).
I try to use getPreviousSibling, but it returns . (dot) and not fn.
Is there a better way to get the previous node instead to do getPreviousSibling().getPreviousSibling()?
import { Project, SyntaxKind } from "ts-morph";
console.clear();
const project = new Project();
const file = project.createSourceFile(
"foo.ts",
`
const fn = () => {}
const fn2 = fn.bind(this);
`
);
const identifiers = file.getDescendantsOfKind(SyntaxKind.Identifier);
const bind = identifiers.find((i) => i.getText() === "bind");
console.log({ bind });
const fn = bind?.getPreviousSibling();
console.log({ fn: fn?.getText() }); //<-- returns . but I was expected to fn.

You can try to use Putout code transformer I'm working on. It has support of template values like
__aand__b, and when you need to change the name, you just put something likehelloin place of__a:It will output identifiers you need:
You can try it in Putout Editor.
And produce changes:
It much simpler then using imperative approach of searching for each previous sibling.