gpt4 book ai didi

javascript - 如何让我的类装饰器只在继承链中最外层的类上运行?

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:58 25 4
gpt4 key购买 nike

我正在使用 class-validator装饰器在运行时验证涉及来 self 的应用程序外部的数据的数据类。我希望我的类在实例化时验证自己。我已经编写了一个类装饰器来轻松地将此功能添加到类中。

import * as t from 'class-validator';

interface Class {
new(...args: any[]): {};
}

export function autoValidate<T extends Class>(target: T) {
return class extends target {
constructor(...args: any[]) {
super(...args);

const errors = t.validateSync(this);

if (errors.length > 0) {
throw errors;
}
}
};
}

这个类装饰器的问题在于,当继承发挥作用时,类及其祖先都用这个装饰器装饰。

@autoValidate
class Parent {
@t.IsNumber()
readonly age: number;

@t.IsString()
readonly name: string;

constructor(age: number, name: string) {
this.age = age;
this.name = name;
}
}

@autoValidate
class Child extends Parent {
@t.IsBoolean()
readonly happy: boolean;

constructor(age: number, name: string, happy: boolean) {
super(age, name);

this.happy = happy;
}
}

Child被实例化,验证器将在 Parent 中抛出错误super 时的构造函数装饰器在 Child 中调用的构造函数/装饰器,因为 happyundefined .

我怎样才能改变我的装饰器,让它只在 this 时运行它的验证代码?是 target 的实例但不是 target 的后代?

最佳答案

基于 Patrick Roberts 的想法的解决方案,针对定义子类和忘记 @autoValidate(否则将导致根本不进行验证)提供额外保护:

import * as t from 'class-validator';

interface Class {
new(...args: any[]): {};
}

const lastClassWithValidation = Symbol();
export function autoValidate<T extends Class>(target: T) {
return class extends target {
static [lastClassWithValidation] = target;
constructor(...args: any[]) {
super(...args);

if ((<any>this.constructor)[lastClassWithValidation] === target) {
const errors = t.validateSync(this);

if (errors.length > 0) {
throw errors;
}
}
}
};
}

关于javascript - 如何让我的类装饰器只在继承链中最外层的类上运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52958269/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com