typescript 在打字稿中获取类的属性

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/41959488/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 04:13:23  来源:igfitidea点击:

Get properties of class in typescript

javascripttypescript

提问by Ramzy Abourafeh

I've the following class:

我有以下课程:

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;
        };
    }

I need to iterate over the properties in a specific class, I tried the following:

我需要遍历特定类中的属性,我尝试了以下操作:

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

But the problem that this iterate just over the privatefields, I tried also the following I got all the methodsand properties:

但是这个问题只是在private字段上迭代,我也尝试了以下我得到的所有methodsproperties

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

Does anyone have a solution?

有没有人有办法解决吗?

Thanks!

谢谢!

采纳答案by Nitzan Tomer

If you need to only get the getters/setters, then you'll need to do something like:

如果您只需要获取 getter/setter,那么您需要执行以下操作:

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"]

(code in playground)

操场上的代码



You can put the static methods in a base class, and then when you extend it the subclass will have those static methods as well:

您可以将静态方法放在基类中,然后当您扩展它时,子类也将具有这些静态方法:

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

(code in playground)

操场上的代码

If you want these methods to be instance methods then you can do this:

如果您希望这些方法成为实例方法,那么您可以这样做:

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"
        });
    }
}

The change is that instead of using this.prototypeyou're using this.constructor.prototype.
Then you simply:

变化在于,this.prototype您使用的是this.constructor.prototype.
然后你只需:

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

(code in playground)

操场上的代码



Edit

编辑

Based on a comment by @Twois, who pointed out that it won't work when targetting es6, here's a version that will work:

根据@Twois 的评论,他指出它在定位 es6 时不起作用,这里有一个可以工作的版本:

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

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

The main difference: using Reflect.ownKeys(this.prototype)instead of Object.keys(this.prototype).

主要区别:使用Reflect.ownKeys(this.prototype)代替Object.keys(this.prototype).

回答by Stef van den Berg

What you can do is for the class you want to use it extend the class above and make the properties public for this reason;

您可以做的是为您想要使用的类扩展上面的类并因此将属性设为公开;

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

And in your Test class make the private protected:

并在您的 Test 类中进行私有保护:

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;
    };
}

Then you should be able to iterate over the properties in an external class;

然后你应该能够迭代外部类中的属性;

But if you want to have the values; Why not make a function that exposes the values by returning them in an array or log them as a string;

但如果你想拥有这些价值观;为什么不通过在数组中返回值或将它们记录为字符串来创建一个公开值的函数;