Class Typescript-编译后获取未初始化的属性

Class Typescript-编译后获取未初始化的属性,class,typescript,reflection,socket.io,Class,Typescript,Reflection,Socket.io,我目前正在围绕socket.io编写一个包装器。从一个非常面向对象的背景出发,我想在我的框架/包装器中实现模型的概念 如果您碰巧知道socket.io,您可能知道您将获取与事件关联的数据作为参数,现在我已经实现了一个自定义路由系统,其中路由处理程序将获取类似于express.js的请求对象中的数据 我们的想法是让模型类看起来像这样: class XRequestModel @v.String({ message: 'The username must be a string!' }) p

我目前正在围绕socket.io编写一个包装器。从一个非常面向对象的背景出发,我想在我的框架/包装器中实现模型的概念

如果您碰巧知道socket.io,您可能知道您将获取与事件关联的数据作为参数,现在我已经实现了一个自定义路由系统,其中路由处理程序将获取类似于express.js的请求对象中的数据

我们的想法是让模型类看起来像这样:

class XRequestModel
  @v.String({ message: 'The username must be a string!' })
  public userName: string;
}
@RouteConfig({ route: '/something', model: XRequestModel })
class XEvent extends Route {
  public on(req: Request<XRequestModel>, res: Response) {
    // Handle Event
  }
}
路由事件可能如下所示:

class XRequestModel
  @v.String({ message: 'The username must be a string!' })
  public userName: string;
}
@RouteConfig({ route: '/something', model: XRequestModel })
class XEvent extends Route {
  public on(req: Request<XRequestModel>, res: Response) {
    // Handle Event
  }
}
但是我认为这会导致一些非常冗长的语法,我不想强迫这个包装器的用户初始化所有的模型属性

实施方面的注意事项:

框架的用户必须将这些类注册到一个“main”类,从那里我可以通过decorator反射获得Route类

当我尝试在没有初始化属性的情况下获取模型的属性时-第一个模型示例

// Here the route.config.model refers to the model from the RouteConfig
Object.getOwnPropertyNames(new route.config.model());
>>> []
以下是初始化属性的结果:

Object.getOwnPropertyNames(new route.config.model());
>>> [ 'userName' ]
此处是指向GitHub存储库的链接: 请注意,模型尚未在本回购协议中实施


基本上,我的问题是:如何在编译后获得具有未初始化属性的类的属性。

问题是,如果没有进行初始化,则不会为字段发出代码,因此在运行时,该字段在对象上不存在,直到为其赋值

最简单的解决方案是初始化所有字段,即使只使用null:

class XRequestModel {
    public userName: string = null;
    public name: string = null;
}
var keys = Object.getOwnPropertyNames(new XRequestModel())
console.log(keys); // [ 'userName', 'name' ]
如果这对您来说不是一个可行的解决方案,那么您可以创建一个decorator,将其添加到类上的静态字段中,并沿着原型链向上走,以获取所有字段:

function Prop(): PropertyDecorator {
    return (target: Object, propertyKey: string): void => {
        let props: string[]
        if (target.hasOwnProperty("__props__")) {
            props = (target as any)["__props__"];
        } else {
            props = (target as any)["__props__"] = [];
        }
        props.push(propertyKey);
    };
}

class XRequestModelBase {
    @Prop()
    public baseName: string;
}

class XRequestModel extends XRequestModelBase {
    @Prop()
    public userName: string;
    @Prop()
    public name: string;
}
function getAllProps(cls: new (...args: any[]) => any) : string[] {
    let result: string[] = [];
    let prototype = cls.prototype;
    while(prototype != null) {
        let props: string[] = prototype["__props__"];
        if(props){
            result.push(...props);
        }
        prototype = Object.getPrototypeOf(prototype);
    }
    return  result;
}
var keys = getAllProps(XRequestModel);
console.log(keys); 

问题是,如果没有进行初始化,则不会为字段发出任何代码,因此在运行时,在为对象分配值之前,该字段不存在于对象上

最简单的解决方案是初始化所有字段,即使只使用null:

class XRequestModel {
    public userName: string = null;
    public name: string = null;
}
var keys = Object.getOwnPropertyNames(new XRequestModel())
console.log(keys); // [ 'userName', 'name' ]
如果这对您来说不是一个可行的解决方案,那么您可以创建一个decorator,将其添加到类上的静态字段中,并沿着原型链向上走,以获取所有字段:

function Prop(): PropertyDecorator {
    return (target: Object, propertyKey: string): void => {
        let props: string[]
        if (target.hasOwnProperty("__props__")) {
            props = (target as any)["__props__"];
        } else {
            props = (target as any)["__props__"] = [];
        }
        props.push(propertyKey);
    };
}

class XRequestModelBase {
    @Prop()
    public baseName: string;
}

class XRequestModel extends XRequestModelBase {
    @Prop()
    public userName: string;
    @Prop()
    public name: string;
}
function getAllProps(cls: new (...args: any[]) => any) : string[] {
    let result: string[] = [];
    let prototype = cls.prototype;
    while(prototype != null) {
        let props: string[] = prototype["__props__"];
        if(props){
            result.push(...props);
        }
        prototype = Object.getPrototypeOf(prototype);
    }
    return  result;
}
var keys = getAllProps(XRequestModel);
console.log(keys);