Получить свойства класса в typescript

У меня есть следующий класс:

export class Test {

        private _rowsCount: string;
        public get RowsCount(): string {
            return this._rowsCount;
        };
        public set RowsCount(value: string) {
            this._rowsCount = value;
        };

        private _rowsCount2: string;
        public get RowsCount2(): string {
            return this._rowsCount2;
        };
        public set RowsCount2(value: string) {
            this._rowsCount2 = value;
        };
    }

Мне нужно перебирать свойства в определенном классе, я пробовал следующее:

Object.keys(this).forEach((key)=> {
    console.log(key);
});

Но проблема в том, что это итерация только над полями private, я также попробовал следующее: я получил все methods и properties:

    for (var property in this) {
        if (this.hasOwnProperty(property)) {
            console.log(property);                
        }
    }

У кого-нибудь есть решение?

Спасибо!

Ответ 1

Если вам нужно только получить геттеры/сеттеры, вам нужно будет сделать что-то вроде:

class Test {
    ...

    public static getGetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["get"] === "function"
        });
    }

    public static getSetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["set"] === "function"
        });
    }
}

Test.getGetters(); // ["RowsCount", "RowsCount2"]
Test.getSetters(); // ["RowsCount", "RowsCount2"]

(код на игровой площадке)


Вы можете поместить статические методы в базовый класс, а затем, когда вы его расширите, подкласс также будет иметь эти статические методы:

class Base {
    public static getGetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["get"] === "function"
        });
    }

    public static getSetters(): string[] {
        return Object.keys(this.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.prototype, name)["set"] === "function"
        });
    }
}

class Test extends Base {
   ...
}

Test.getGetters(); // work the same

(код на игровой площадке)

Если вы хотите, чтобы эти методы были методами экземпляра, вы можете сделать это:

class Base {
    public getGetters(): string[] {
        return Object.keys(this.constructor.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.constructor.prototype, name)["get"] === "function"
        });
    }

    public getSetters(): string[] {
        return Object.keys(this.constructor.prototype).filter(name => {
            return typeof Object.getOwnPropertyDescriptor(this.constructor.prototype, name)["set"] === "function"
        });
    }
}

Изменение заключается в том, что вместо this.prototype вы используете this.constructor.prototype.
Тогда вы просто:

let a = new Test();
a.getGetters(); // ["RowsCount", "RowsCount2"]

(код на игровой площадке)

Ответ 2

Что вы можете сделать для класса, который вы хотите использовать, расширяет класс выше и делает свойства общедоступными по этой причине;

   class TestExposed extend Test {
      public _rowsCount: string;
      public _rowsCount2: string; 
   }

И в вашем классе Test сделайте private protected:

class Test {
    protected _rowsCount: string;
    public get RowsCount(): string {
        return this._rowsCount;
    };
    public set RowsCount(value: string) {
        this._rowsCount = value;
    };

    protected _rowsCount2: string;
    public get RowsCount2(): string {
        return this._rowsCount2;
    };
    public set RowsCount2(value: string) {
        this._rowsCount2 = value;
    };
}

Затем вы должны иметь возможность перебирать свойства во внешнем классе;

Но если вы хотите иметь значения; Почему бы не сделать функцию, которая предоставляет значения, возвращая их в массив или записывая их как строку,