Получить ключи интерфейса Typcript как массив строк

У меня много таблиц в Lovefield и их соответствующих интерфейсах для тех столбцов, которые у них есть.
Пример:

export interface IMyTable {
  id: number;
  title: string;
  createdAt: Date;
  isDeleted: boolean;
}

Я хотел бы иметь имена свойств этого интерфейса в таком массиве:

var IMyTable = ["id", "title", "createdAt", "isDeleted"];

Я не могу сделать объект/массив на основе интерфейса IMyTable напрямую, что должно сделать трюк, потому что я получаю имена имен таблиц динамически. Следовательно, мне нужно перебрать эти свойства в интерфейсе и получить массив из него.

Как достичь этого результата.

Ответ 1

Начиная с TypeScript 2.3 (или, я должен сказать, 2.4, как и в 2.3, эта функция содержит ошибку, которая была исправлена в [email protected]), вы можете создать собственный трансформатор для достижения того, что вы хотите сделать.

На самом деле, я уже создал такой настраиваемый трансформатор, который позволяет следующее.

https://github.com/kimamula/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']

К сожалению, пользовательские трансформаторы в настоящее время не так просты в использовании. Вы должны использовать их с API-интерфейсом преобразования TypeScript вместо выполнения команды tsc. Существует проблема с запросом поддержки плагинов для настраиваемых трансформаторов.

Ответ 2

Не могу. Интерфейсы не существуют во время выполнения.

обходной путь

Создайте переменную типа и используйте Object.keys на ней 🌹

Ответ 3

Вам нужно будет создать класс, который реализует ваш интерфейс, Object.keys(yourObject) его экземпляр, а затем воспользуемся Object.keys(yourObject) чтобы получить свойства.

export class YourClass implements IMyTable {
    ...
}

затем

let yourObject:YourClass = new YourClass();
Object.keys(yourObject).forEach((...) => { ... });

Ответ 4

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

Итак, для вашего примера, определите/создайте свой класс следующим образом:

export class IMyTable {
    constructor(
        public id = '',
        public title = '',
        public createdAt: Date = null,
        public isDeleted = false
    )
}

Используйте его как интерфейс:

export class SomeTable implements IMyTable {
    ...
}

Получить ключи:

const keys = Object.keys(new IMyTable());

Ответ 5

Следующее требует, чтобы вы перечислили ключи по своему усмотрению, но по крайней мере TypeScript обеспечит, чтобы IUserProfile и IUserProfileKeys имели точно такие же ключи ( Required<T> было добавлено в TypeScript 2.8):

export interface IUserProfile  {
  id: string;
  name: string;
};
type KeysEnum<T> = { [P in keyof Required<T>]: true };
const IUserProfileKeys: KeysEnum<IUserProfile> = {
  id: true,
  name: true,
};

Ответ 6

Это должно работать

var IMyTable: Array<keyof IMyTable> = ["id", "title", "createdAt", "isDeleted"];

или

var IMyTable: (keyof IMyTable)[] = ["id", "title", "createdAt", "isDeleted"];

Ответ 7

// declarations.d.ts
export interface IMyTable {
      id: number;
      title: string;
      createdAt: Date;
      isDeleted: boolean
}
declare var Tes: IMyTable;
// call in annother page
console.log(Tes.id);