'compile-time' way to get all property names defined interface

后端 未结 4 1360
心在旅途
心在旅途 2020-12-03 05:00

I\'d like to create a generic TypeScript class for rendering (as a HTML list) of an array of objects which implement a specific interface.

e.g.

相关标签:
4条回答
  • 2020-12-03 05:08

    This is not possible to retrieve that information at runtime, and they will never be per default possible unless you store them during the compilation. The solution is therefore be in reflection using ReflectDecorators.

    Here is an excellent article covering the question of retrieving compilation time metadata at the runtime. In short: you add a decorator to the interface you would like to keep the description, this one will be converted to a JSON object which one will be stored into the code itself. During the runtime, you will be able to retrieve this JSON object having all the interface data. This is now experimental (11th Feb 2016) but in a good way.

    Note: The reason why it will never by per default is basically a choice of design for TS not to overload the js code with metadata (unlike Dart).

    0 讨论(0)
  • 2020-12-03 05:14

    At runtime all of the type information is erased, so the best you can do is enumerate the properties of one of the objects. This will give you back all properties, even those that were not on the specified interface.

    class GenericListRenderer<T> {
    
        constructor(private items: T[], private className?: string){
    
        }
    
        private getPropertyNames(): string[] {
            var properties: string[] = [];
    
            if (this.items.length > 0) {
                for (var propertyName in this.items[0]) {
                    console.log(propertyName);
                    properties.push(propertyName);
                }
            }
    
            return properties;
        }
    
        render(){
          var propNames: string[] = this.getPropertyNames();
        }
    
    }
    
    class Example {
        constructor(public name: string) {
    
        }
    }
    
    var example = new Example('Steve');
    
    var a = new GenericListRenderer<Example>([example]);
    
    a.render();
    

    There is also Object.keys(), which gives you back all of the properties, although it is only supported in IE9 and above.

    If you can supply more of a use case for what you want to do with the properties, it may be possible to give you an alternate solution using attributes or some other mechanism.

    0 讨论(0)
  • 2020-12-03 05:19

    This is possible by using custom transformers introduced by https://github.com/Microsoft/TypeScript/pull/13940, which is available in typescript >= 2.4.1.

    My npm package, ts-transformer-keys, is a good example.

    import { keys } from 'ts-transformer-keys';
    
    interface Props {
      id: string;
      name: string;
      age: number;
    }
    const keysOfProps = keys<Props>();
    
    console.log(keysOfProps); // ['id', 'name', 'age']
    
    0 讨论(0)
  • 2020-12-03 05:23

    You can get all the information you need by calling

    let test = Object.keys(instanceOfObject)
    

    If you log this console.log(test), you get something like:

    0: "user_id"
    ...
    26: "address"
    length: 27
    

    you can access every information on this object, such as test.length etc.

    From: https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

    0 讨论(0)
提交回复
热议问题