我在Lovefield中有很多表,以及它们各自的接口,说明它们有哪些列。

例子:

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

我想有这个接口的属性名在这样的数组中:

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

我不能直接基于接口IMyTable创建一个对象/数组,因为我将动态地获得表的接口名称。因此,我需要在接口中迭代这些属性,并从中获得一个数组。

我如何实现这个结果?


当前回答

这是一个艰难的问题!谢谢大家的帮助。

我的需要是将接口的键作为字符串数组来简化mocha/chai脚本。不关心在应用程序中使用(还),所以不需要创建ts文件。感谢ford04的帮助,他上面的解决方案是一个巨大的帮助,它的工作完美,没有编译器黑客。下面是修改后的代码:

选项2:基于TS编译器API的代码生成器(TS -morph)

节点模块

npm install --save-dev ts-morph

keys.ts

注意:这里假设所有ts文件都位于./src的根目录下,并且没有子文件夹,请相应地调整

import {
  Project,
  VariableDeclarationKind,
  InterfaceDeclaration,
} from "ts-morph";

// initName is name of the interface file below the root, ./src is considered the root
const Keys = (intName: string): string[] => {
  const project = new Project();
  const sourceFile = project.addSourceFileAtPath(`./src/${intName}.ts`);
  const node = sourceFile.getInterface(intName)!;
  const allKeys = node.getProperties().map((p) => p.getName());

  return allKeys;
};

export default Keys;

使用

import keys from "./keys";

const myKeys = keys("MyInterface") //ts file name without extension

console.log(myKeys)

其他回答

你需要创建一个类来实现你的接口,实例化它,然后使用Object.keys(yourObject)来获取属性。

export class YourClass implements IMyTable {
    ...
}

then

let yourObject:YourClass = new YourClass();
Object.keys(yourObject).forEach((...) => { ... });
// 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);

这是一个艰难的问题!谢谢大家的帮助。

我的需要是将接口的键作为字符串数组来简化mocha/chai脚本。不关心在应用程序中使用(还),所以不需要创建ts文件。感谢ford04的帮助,他上面的解决方案是一个巨大的帮助,它的工作完美,没有编译器黑客。下面是修改后的代码:

选项2:基于TS编译器API的代码生成器(TS -morph)

节点模块

npm install --save-dev ts-morph

keys.ts

注意:这里假设所有ts文件都位于./src的根目录下,并且没有子文件夹,请相应地调整

import {
  Project,
  VariableDeclarationKind,
  InterfaceDeclaration,
} from "ts-morph";

// initName is name of the interface file below the root, ./src is considered the root
const Keys = (intName: string): string[] => {
  const project = new Project();
  const sourceFile = project.addSourceFileAtPath(`./src/${intName}.ts`);
  const node = sourceFile.getInterface(intName)!;
  const allKeys = node.getProperties().map((p) => p.getName());

  return allKeys;
};

export default Keys;

使用

import keys from "./keys";

const myKeys = keys("MyInterface") //ts file name without extension

console.log(myKeys)

这应该可以

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

or

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

从TypeScript 2.3(或者我应该说2.4,因为在2.3这个特性包含一个bug,该bug已在typescript@2.4-dev中修复)开始,你可以创建一个自定义转换器来实现你想要做的事情。

实际上,我已经创建了这样一个自定义转换器,它支持以下功能。

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

不幸的是,定制变压器目前还不太容易使用。你必须将它们与TypeScript转换API一起使用,而不是执行tsc命令。有一个问题,要求插件支持自定义变压器。