如何获取公共字段/属性名称的数组?

时间:2017-04-04 09:43:12

标签: typescript metaprogramming

说我有一个打字稿类:

class Person
{
    constructor(public readonly firstName: string, public readonly lastName: string, public readonly id: number)
    {

    }
}

我想使用一些通用函数列出给定类的所有公共属性。

所以假设的 getAllPublicProps< ...> 会像这样使用:

const allPublicProps: (keyof Person)[] = getAllPublicProps<Person>() ;

并返回等同于['firstName','lastName','id']的字符串数组。

2 个答案:

答案 0 :(得分:1)

如果你能接受一点点丑陋,例如实例化类并接受它不会理解私有属性和公共属性之间的区别(除非你以某种方式编码),这有点可能。

假设你有你的班级

class Person {
  constructor(public readonly firstName: string, 
              public readonly lastName: string,
              public readonly id: number,
              private readonly _secret: number) {}
}

您可以编写一个util方法

class Util {
  static getProperties(obj: any): string[] {
    const result = [];
    for (let property in obj) {
      if (obj.hasOwnProperty(property) && !property.startsWith('_')) {
        result.push(property);
      }
    }
    return result;
  }
}

并使用它

const allProperties = Util.getProperties(new Person());

答案 1 :(得分:0)

在不知道确切用例的情况下,很难给出具体答案。 但我会尝试:)

由于TypeScript的类型注释仅在编译时而非运行时可用,因此编译时的属性之间不存在真正的差异。例如:

class Person {
    private secret = '123';
    constructor(
        public readonly firstName: string,
        public readonly lastName: string,
        public readonly id: number
    ) { }
}

将编译为

var Person = (function () {
    function Person(firstName, lastName, id) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.id = id;
        this.secret = '123';
    }
    return Person;
}());

此外,虽然type PersonProperties = keyof Person将为您提供所有公共属性的字符串文字类型,但您不能使用此类型来过滤任何内容,因为它只是一个注释。因此,您只能使用PersonProperties进行功能签名。

猜猜你可以使用Reflect,但这包括对公共属性进行硬编码。此外,Angular的编译器滥用TS编译器来编写在编译期间可用的元数据。如果有任何框架无关的lib也可以这样做,我现在不会。