我正在写一个通用的unmarshaller。它将图形DB数据转换为生成的TypeScript(1.8.7)模型类。输入是JSON。输出应该是模型类的实例 我的最终目标是创建类似Hibernate OGM的东西,仅用于Tinkerpop Frames和TypeScript,中间有REST端点。
将一个类作为参数传递给它的静态成员的正确方法是什么?我想要这样的东西:
SomeModel some = <SomeModel> unmarshaller.fromJSON({/*Object from JSON*/}, SomeModel);
我试过写一个方法。 不确定我是否朝着正确的方向前进,随意提出不同的方法。
public fromJSON(input: Object, clazz: typeof FrameModel): FrameModel
{
// This only demonstrates access to Framemodel's metadata
// about original Java model classes.
clazz.graphPropertyMapping;
clazz.graphRelationMapping;
let result = {};
...
return result;
}
...
但是当我尝试在Plunker上执行此操作时,我遇到了无用堆栈跟踪的执行错误。
模型超类看起来像这样:
/**
* Things common to all Frames models on the Typescript side.
*/
export class FrameModel
{
// Model metadata
static discriminator: string;
static graphPropertyMapping: { [key:string]:string; };
static graphRelationMapping: { [key:string]:string; };
// Each instance needs a vertex ID
private vertexId: number;
public getVertexId(): number {
return this.vertexId;
}
}
样本模型类:
import {TestPlanetModel} from './TestPlanetModel';
import {TestShipModel} from './TestShipModel';
export class TestGeneratorModel extends FrameModel
{
static discriminator: string = 'TestGenerator';
static graphPropertyMapping: { [key:string]:string; } = {
bar: 'boo',
name: 'name',
rank: 'rank',
};
static graphRelationMapping: { [key:string]:string; } = {
colonizes: 'colonizedPlanet',
commands: 'ship',
};
boo: string;
name: string;
rank: string;
public colonizedPlanet: TestPlanetModel[]; // edge label 'colonizedPlanet'
public ship: TestShipModel; // edge label 'ship'
}
我在TypeScript中找不到很多关于反射和类处理的材料 我知道如何用Java做到这一点 我知道如何在JavaScript中执行此操作 我知道我可能会使用装饰器获得类似的结果,但对于生成的模型,使用字段或静态字段似乎更简单。
答案 0 :(得分:0)
您可能已经注意到,班级成员不能拥有const
个关键字。但你可以选择static
。如果您希望成员可以从外部访问,则该成员也应该是公开的。
public static graphPropertyMapping: { [key:string]:string; } = {
bar: 'boo',
name: 'name',
rank: 'rank',
};
至于创建结果实例:
let result = new clazz();
//copy properties
return result;
答案 1 :(得分:0)
如果我理解正确,那么这里可以帮助您入门:
interface Model {}
interface ModelData {}
interface MyModelConstructor<M extends Model, D extends ModelData> {
new(data: D): M;
// static members
graphPropertyMapping: any;
graphRelationMapping: any;
}
class Unmarshaller {
public fromJSON<T>(input: string | ModelData, ctor: MyModelConstructor<T, ModelData>): T {
let data: ModelData = (typeof input === "string") ? JSON.parse(input) : input;
let propertyMapping = ctor.graphPropertyMapping;
let relationMapping = ctor.graphRelationMapping;
// do whatever with the mappings
return new ctor(input);
}
}
我不知道你的模特是什么样子的,所以我希望它足够接近。
答案 2 :(得分:0)
我最近发布了TypeScript编译器的增强版本,它可以准确地提供您所期望的内容:从类中读取所有(静态或非静态)字段元数据。例如,你可以写:
interface MyInterface {
active:boolean;
description: string;
}
class MyClass {
id: number;
name: string;
myComplexField: MyInterface;
}
function printMembers(clazz: Class) {
let fields = clazz.members.filter(m => m.type.kind !== 'function'); //exclude methods.
for(let field of fields) {
let typeName = field.type.kind;
if(typeName === 'class' || typeName === 'interface') {
typeName = (<Class | Interface>field.type).name;
}
console.log(`Field ${field.name} of ${clazz.name} has type: ${typeName}`);
}
}
printMembers(MyClass.getClass());
这是输出:
$ node main.js
Field id of MyClass has type: number
Field name of MyClass has type: string
Field myComplexField of MyClass has type: MyInterface
当然,如果您将clazz的members
属性访问权限更改为statics
,您将检索所有静态成员。这些信息也可以在编码时访问,因此您可以使用自动完成功能。
您可以使用Interfaces元数据执行相同操作。只需编写MyInterface
例如,并访问其成员。
您可以找到项目here。