【问题标题】:extending existing validator and only set some options扩展现有验证器并仅设置一些选项
【发布时间】:2020-07-27 19:36:45
【问题描述】:

我的数据库列的类型是双精度(来自Postgres docs

双精度 8 字节可变精度,不精确的 15 位小数精度

使用类验证器我想进行精度检查

@IsNumber()
/* precision check */
public myValue: number;

IsDecimal 装饰器在这里可能会有所帮助,所以 @IsDecimal({ decimal_digits: '15' }) 可能会起到作用。我必须将这个装饰器用于多个字段,有没有办法扩展现有的装饰器并传入decimal_digits 选项?我认为重新发明轮子没有意义。如果我可以继承验证但将精度设置为小于或等于 15,那就太好了。

目前我创建了自己的装饰器

@ValidatorConstraint()
class IsDoublePrecisionConstraint implements ValidatorConstraintInterface {
    public validate(value: any): boolean {
        if (typeof value === 'number') {
            if (value % 1 === 0) {
                return true;
            }

            const valueText: string = value.toString();
            const valueSegments: string[] = valueText.split('.');
            const decimalDigits: string = valueSegments[1];

            return decimalDigits.length <= 15;
        }

        return false;
    }

    public defaultMessage(args: ValidationArguments): string {
        return `${args.property} must have less than or equal to 15 decimal digits.`;
    }
}

export function IsDoublePrecision() {
    return (object: Record<string, any>, propertyName: string) => {
        registerDecorator({
            target: object.constructor,
            propertyName,
            validator: IsDoublePrecisionConstraint,
        });
    };
}

但我不确定这个是否能够处理所有案件。

提前致谢

【问题讨论】:

    标签: typescript typescript-decorator class-validator


    【解决方案1】:

    我没有找到任何关于扩展class-validator的现有装饰器的示例,但是IsDecimal只是一个普通的属性装饰器,那么我们可以将它用作属性装饰器。

    我的想法是创建一个“普通”属性装饰器,并在此装饰器中调用 IsDecimal 并使用 decimal_digits 选项。

    // function as a const
    export const IsDoublePrecision = () => { // use decorator factory way
      return (target: object, key: string) => { // return a property decorator function
        IsDecimal({ decimal_digits: '15' })(target, key); // call IsDecimal decorator
      }
    }
    

    用法:

    @IsNumber()
    /* precision check */
    @IsDoublePrecision()
    public myValue: number;
    

    【讨论】:

    • 非常感谢,您介意在这里解释一下速记语法吗? IsDecimal({ decimal_digits: '15' })(target, key);我没见过 :)
    • 其次,我通过传入各种值(如48.444548.44454684564587884754545648745894848.123456789112345)对此进行了测试,但每次收到此错误消息时:(“值不是有效的十进制数。 "
    • 抱歉打扰了,我也创建了自己的装饰器并更新了我的问题
    • @Question3r 太多人认为我的代码需要解释一下,但总的来说,IsDecimal 是一个装饰器工厂,当你调用IsDecimal() 时它会返回一个装饰器。属性装饰器将为类创建一些metadata,用于存储关于属性名称和验证类型的元数据......它将在class-validatorvalidate 函数中使用。调用(target, key) 正在为使用IsDoublePrecision 的类应用IsDecimal 的逻辑。
    • 我不知道IsDecimal 的确切规格,但是当您在相同的测试用例中使用@IsDecimal({ decimal_digits: '15' }) 而不是IsDoublePrecision 时,您会得到同样的错误。当myValue 是类似的数字字符串时,它将通过。
    猜你喜欢
    • 1970-01-01
    • 2017-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2011-07-25
    • 2023-03-04
    相关资源
    最近更新 更多