TypeScript-将类作为参数传递并进行反射 [英] TypeScript - passing a class as an argument, and reflection

查看:1785
本文介绍了TypeScript-将类作为参数传递并进行反射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在写一个通用的解组器.它将图形数据库数据转换为生成的TypeScript(1.8.7)模型类.输入为JSON.输出应该是模型类的实例.
我的最终目标是创建仅适用于Tinkerpop Frames和TypeScript的Hibernate OGM之类的东西,而REST端点位于中间.

I am writing a generic unmarshaller. It converts graph DB data to generated TypeScript (1.8.7) model classes. The input is JSON. The output should be an instance of a model class.
My ultimate goal is to create something like Hibernate OGM, only for Tinkerpop Frames and TypeScript, with REST endpoint in the middle.

将类作为参数传递并达到其静态成员的正确方法是什么?我想要这样的东西:

SomeModel some = <SomeModel> unmarshaller.fromJSON({/*Object from JSON*/}, SomeModel);

我试图写一个方法. 不确定我是否朝着正确的方向前进,请随时提出不同的建议.

I've tried to write a method. Not sure if I am heading in the right direction, feel free to suggest different approaches.

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上执行此操作时,由于堆栈跟踪无效而出现执行错误.

But when I tried to execute this on Plunker, I got execution errors with unuseful stacktrace.

模型超类如下:

/**
 * 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进行此操作.
我知道使用装饰器可以达到类似的结果,但是对于生成的模型而言,具有字段或静态字段似乎要简单一些.

I haven't found much material on reflection and class handling in TypeScript.
I know how I would do this in Java.
I know how I would do this in JavaScript.
I understand that I might achieve similar results with decorators, but having fields or static fields seemed a bit simpler, for generated models.

推荐答案

我最近发布了TypeScript编译器的增强版本,该版本可以完全满足您的期望:从类中读取所有(静态的)字段元数据.例如,您可以编写:

I recently released an enhanced version of the TypeScript compiler that allows exactly what you are expecting: read all (static or not) fields metadata from a class. For example you can write:

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并访问其成员. 您可以在此处找到项目.

Of course, if you change the members property access of clazz to statics you will retrieve all static members. These information can be accessed at coding time too, so you can use autocompletion. You can do the same with Interfaces metadata. Simply write MyInterface for example, and access its members. You can find the project here.

这篇关于TypeScript-将类作为参数传递并进行反射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆