是否可以在运行时传递 Typescript 装饰器对象值?

Is it possible to pass Typescript decorator object values in at runtime?

我有一个 class 装饰有这样的 @MinDate 约束:

export default class Order {
   purchaseDate: Date;
   @MinDate(this.purchaseDate)
   receiptDate: Date;
}

当试图验证一个有效的 Order 实例时,验证错误。我的问题是是否有可能/有效地将 this.purchaseDate 作为参数传递给 @MinDate() 装饰器。

换句话说,打字稿装饰器可以从对象接收运行时值,还是这些值必须在编译时可用?例如:

@MinDate(new Date(12/22/2017));  //This should work?
@MinDate(this.someDate) // This will never work?

不,你不能那样做。
装饰器应用于 类 而不是实例,这意味着调用装饰器函数时没有 this

使用静态值可以:

@MinDate(new Date(12/22/2017));

但是您不能为其使用实例成员。

您可以在没有装饰器的构造函数中执行此操作:

export default class Order {
    ...
    constructor() {
        this.purchaseDate = ...
        this.receiptDate = this.purchaseDate;
    }
}

可以使用自定义验证器:

    import {registerDecorator, ValidationOptions, ValidationArguments} from "class-validator";

export function IsGreaterThan(property: string, validationOptions?: ValidationOptions) {
   return function (object: Object, propertyName: string) {
        registerDecorator({
            name: "IsGreaterThan",
            target: object.constructor,
            propertyName: propertyName,
            constraints: [property],
            options: validationOptions,
            validator: {
                validate(value: any, args: ValidationArguments) {
                    const [relatedPropertyName] = args.constraints;
                    const relatedValue = args.object[relatedPropertyName];
                    return value > relatedValue;
                }
            }
        });
   };
}

用法:

import { IsGreaterThan } from "./IsLongerThan";

export class Post {
    purchaseDate: string;

    @IsGreaterThan("purchaseDate", { message: "receiptDate must be greater than purchaseDate" })
    text: string;
}

可以在文档中找到更多详细信息:https://github.com/typestack/class-validator#custom-validation-decorators