How can I determine if a class member is a getter or setter?

39 Views Asked by At

I am trying to use ts-morph to validate code in a transpiler I am writing. No it is not a TypeScript transpiler, but I need to support both JS and TS code within my original file.

I have the following code: (classObj is one of the classes in my original code)

  const classMembers = classObj.getMembers();
  classMembers.forEach(member => {
    const name = member.getName();
    const isMethod = member.isKind(174);
    const isStatic = member.isStatic();
    const isAsync = member.isAsync ? member.isAsync() : false;
    const isPrivate = name.startsWith('#');
    console.log({ name, isMethod, isStatic, isAsync, isPrivate });
  });

I am trying to find out if the current member is a getter or a setter and the Docs are quite limited so I have no idea how to do this. I also read through all the relevant issues and discussions on the GitHub repo and still found nothing that explained how to do this.

Is there a method on member that will tell me if this member is a getter or setter?

I know I can call member.getFullText() and that returns something like this:


    static get val() {
      return this.#_val;
    }

Then I know I can parse that string to see if get or set is used. But I assume that this is already done by ts-morph and I just need to know what to call to fins this out.

This is the example file I am parsing:

class SomeClass {
    #_val = 'dog';
    #money = 19.95;
    bgColor = 'black';

    static async tacos() {
      return 10;
    }

    static get val() {
      return this.#_val;
    }

    static set val(newVal) {
      this.#_val = newVal;
    }

    async doSomething(volume: number): string {
      return 'Boom boom!';
    }

    #update(obj) {
      const {x, y, z} = obj;
    }
  }

And this is the output from the code above:

{
  name: '#_val',
  isMethod: false,
  isStatic: false,
  isAsync: false,
  isPrivate: true
}
{
  name: '#money',
  isMethod: false,
  isStatic: false,
  isAsync: false,
  isPrivate: true
}
{
  name: 'bgColor',
  isMethod: false,
  isStatic: false,
  isAsync: false,
  isPrivate: false
}
{
  name: 'tacos',
  isMethod: true,
  isStatic: true,
  isAsync: true,
  isPrivate: false
}
{
  name: 'val',
  isMethod: false,
  isStatic: true,
  isAsync: false,
  isPrivate: false
}
{
  name: 'val',
  isMethod: false,
  isStatic: true,
  isAsync: false,
  isPrivate: false
}
{
  name: 'doSomething',
  isMethod: true,
  isStatic: false,
  isAsync: true,
  isPrivate: false
}
{
  name: '#update',
  isMethod: true,
  isStatic: false,
  isAsync: false,
  isPrivate: true
}

Any help would be greatly appreciated. Mike

1

There are 1 best solutions below

0
Intervalia On

I figured it out.

Here are the changes I needed:

I needed to import Node:

import { Project, Node } from "ts-morph";

Then I use the static functions on Node:

  const classMembers = classObj.getMembers();
  classMembers.forEach(member => {
    const name = member.getName();
    const isMethod = member.isKind(174);
    const isStatic = member.isStatic();
    const isAsync = member.isAsync ? member.isAsync() : false;
    const isPrivate = name.startsWith('#');
    const isGetter = Node.isGetAccessorDeclaration(member); // here
    const isSetter = Node.isSetAccessorDeclaration(member); // And here

    console.log({ name, isMethod, isStatic, isAsync, isPrivate, isGetter, isSetter });
  });

Now the calculations for the getter and setter are working:

{
  name: 'val',
  isMethod: false,
  isStatic: true,
  isAsync: false,
  isPrivate: false,
  isGetter: true,
  isSetter: false
}
{
  name: 'val',
  isMethod: false,
  isStatic: true,
  isAsync: false,
  isPrivate: false,
  isGetter: false,
  isSetter: true
}