Подтвердить что ты не робот

'время компиляции' способ получить все имена свойств, определенные интерфейсом

Я хотел бы создать общий класс TypeScript для отображения (в виде списка HTML) массива объектов, которые реализуют определенный interface.

например

class GenericListRenderer<T> {
  items: T[];

 constructor(listItems: T[], className?: string){
      this.items = listItems;
      ...
    }

    private getPropertyNames(): string[]{

    // What is the best way to access all property names defined in
    // TypeScript interface 'T' that was used in this generic?
    ...   
    }

    render(){
      var propNames: string[] = this.getPropertyNames();
      // render list with each item containing set of all 
      // key(prop name)/value pairs defined by interface 'T'  
      ...

    }
}

В: что было бы лучшим способом получить список времени компиляции всех имен свойств, определенных в указанном() интерфейсе TypeScript?

Как и шаблоны C++, я полагаю, что TypeScript может разрешать эти обобщенные элементы во время "времени компиляции", когда информация о типе TypeScript (например, интерфейс, предоставленный обобщенному элементу, используемому для создания экземпляра конкретного объекта) легко доступна.

Поскольку вся необходимая информация о типах потенциально предоставляется, мне было просто любопытно, было ли доступно расширение/средство TypeScript для доступа к этой информации без чрезмерной фильтрации во время выполнения "ванильных" объектов Javascript - что может быть проблематично из-за неоднозначных проблем наследования (например, требуемые унаследованные свойства интерфейса TypeScript могут быть отфильтрованы, если для фильтрации свойств используется среда выполнения, generic, Javascript (obj.hasOwnProperty(prop))).

Этот потенциал самоанализа полезного свойства может быть однозначно разрешен с помощью супер-набора метаданных типа TypeScript во время "времени компиляции" против попыток разрешить эту информацию в переведенном Javascript, когда вся эта информация о типах отбрасывается.

Я бы не хотел "изобретать велосипед" с потенциально несовершенным взломом Javascript, если существует стандартный подход (TypeScript).

4b9b3361

Ответ 1

Это возможно с помощью пользовательских преобразователей, представленных https://github.com/Microsoft/TypeScript/pull/13940, который доступен в машинописном тексте> = 2.4.1.

Мой пакет npm, ts-transformer-keys, является хорошим примером.

import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); // ['id', 'name', 'age']

Ответ 2

Это невозможно получить эту информацию во время выполнения, и они никогда не будут по умолчанию возможны, если вы не сохраните их во время компиляции. Поэтому решение должно быть отражено с помощью ReflectDecorators.

Вот отличная статья, посвященная вопросу получения метаданных времени компиляции во время выполнения. Вкратце: вы добавляете декоратор в интерфейс, который хотите сохранить в описании, этот будет преобразован в объект JSON, который будет сохранен в самом коде. Во время выполнения вы сможете получить этот объект JSON, имеющий все данные интерфейса. Сейчас это эксперимент (11 февраля 2016 г.), но в хорошем смысле.

Примечание: причина, по которой он никогда не будет по умолчанию, в основном заключается в том, что TS предпочитает не перегружать код js метаданными (в отличие от Dart).

Ответ 3

Вы не можете. К тому времени, когда это выполняется, оно больше не TypeScript, это простой JavaScript без интерфейсов или сильная типизация.

Вы не можете ссылаться на конструкторы TypeScript во время выполнения.

Ответ 4

Вы можете получить всю необходимую информацию, позвонив по телефону

let test = Object.keys(instanceOfObject)

Если вы зарегистрируете этот console.log (тест), вы получите что-то вроде:

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

Вы можете получить доступ к любой информации об этом объекте, такой как test.length и т.д.

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

Ответ 5

Во время выполнения вся информация о типе стирается, поэтому лучше всего перечислить свойства одного из объектов. Это вернет вам все свойства, даже те, которые не были на указанном интерфейсе.

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();

Существует также Object.keys(), который возвращает все свойства, хотя он поддерживается только в IE9 и выше.

Если вы можете предоставить больше вариантов использования для того, что вы хотите сделать со свойствами, возможно, вам будет предоставлено альтернативное решение с использованием атрибутов или какого-либо другого механизма.