Angular TypeScript属性装饰程序

Angular TypeScript属性装饰程序,angular,typescript,validation,decorator,Angular,Typescript,Validation,Decorator,我希望在模型类本身中隔离模型验证,而不必硬编码必需的状态(我们的设计人员不知道需要什么,只知道他们需要连接属性)。我正在尝试财产装饰的道路,运气不好。构造函数覆盖装饰器设置的内容。这可能吗?我应该换一种方式吗 model.ts @Required name: string; hobbies: string; constructor(dto?: any) { this.name = dto.name; // This clears my "required" property

我希望在模型类本身中隔离模型验证,而不必硬编码必需的状态(我们的设计人员不知道需要什么,只知道他们需要连接属性)。我正在尝试财产装饰的道路,运气不好。构造函数覆盖装饰器设置的内容。这可能吗?我应该换一种方式吗

model.ts

@Required
name: string;

hobbies: string;

constructor(dto?: any) {
    this.name = dto.name; // This clears my "required" property
    this.hobbies = dto.hobbies;
}
function Required(target: any, key: string) {
    Object.defineProperty(target, "required", { value: true });
}
decorator.ts

@Required
name: string;

hobbies: string;

constructor(dto?: any) {
    this.name = dto.name; // This clears my "required" property
    this.hobbies = dto.hobbies;
}
function Required(target: any, key: string) {
    Object.defineProperty(target, "required", { value: true });
}
我希望实现的是

*.html

<input name="name" [(ngModel)]="model.name" [required]="model.name.hasOwnProperty('required')">

你不能像那样在财产中保留额外的信息。属性在指定时将被新值替换,一旦指定新值,将无法访问您指定的非类的原型(并且
目标
原型
不是类的实例)

一个解决方案是添加一个额外的属性,让我们称之为
meta
,它可以保存此元数据(以及其他需要的属性元数据)。您甚至可以使用映射类型正确地键入它。此解决方案非常接近您期望的结果:

class Model {
    readonly meta!: Metadata<Model>
    @Required
    name: string;

    hobbies: string;

    constructor(dto?: any) {
        this.name = dto.name; // This clears my "required" property
        this.hobbies = dto.hobbies;
    }
}
type Metadata<T> = Partial<Record<keyof T, PropertyMetadata>>
type PropertyMetadata = {
    required?: boolean
}
function Required<T extends { meta: Metadata<T> }, TKey extends keyof T>(target: T, key: TKey) {
    let meta = target.meta || (target.meta = {});
    let propMeta = meta[key] || (meta[key] = {})
    propMeta!.required = true
}

console.log(new Model({}).meta.name!.required);
类模型{
只读元数据!:元数据
@必需的
名称:字符串;
爱好:弦乐;
构造函数(dto?:任何){
this.name=dto.name;//这将清除我的“required”属性
this.cabiods=dto.cabiods;
}
}
类型元数据=部分
类型PropertyMetadata={
必需?:布尔值
}
所需功能(目标:T,键:TKey){
设meta=target.meta | |(target.meta={});
设propMeta=meta[key]| |(meta[key]={})
propMeta!.required=true
}
console.log(新模型({}).meta.name!。必需);

请注意,如果没有任何元数据,
meta
可以是未定义的。属性的元数据也可能是未定义的,因此在角度模板中,您应该使用
model.meta?.name?.required
访问它。您也可以做一些更有趣的事情,将
代理
而不是
{}
分配给
,但我在这里走了一条简单的路线。

我不明白您打算如何使用/创建它。你能在上面创建一个应用程序吗?我意识到代码不起作用,但它会传达意图。