Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: Range decorator for numbers #2550

Open
rastorc3v opened this issue Nov 3, 2024 · 2 comments
Open

feature: Range decorator for numbers #2550

rastorc3v opened this issue Nov 3, 2024 · 2 comments
Labels
flag: needs discussion Issues which needs discussion before implementation. type: feature Issues related to new features.

Comments

@rastorc3v
Copy link

Description

There are two string length check decorators: @MinLength and @MaxLength.
Additionally, there is a string decorator @Length(min, max) which checks if string length is in range between min and max.
As a developer, having @Min and @Max decorators for numbers, which works similar to @MinLength and @MaxLength, I would expect the third, @Range(min, max) decorator, to be delivered with class-validator.

Proposed solution

Create a new @range decorator for numbers, which is a combination of Min and Max decorators.

Code implementation suggestion:

import { ValidationOptions } from '../ValidationOptions';
import { buildMessage, ValidateBy } from '../common/ValidateBy';

export const RANGE = 'range';

/**
 * Checks if the first number is greater than or equal to the second and less than or equal to the third.
 */
export function range(num: unknown, min: number, max: number): boolean {
  return typeof num === 'number' && typeof max === 'number' && typeof min === 'number' && min <= num <= max;
}

/**
 * Checks if the value is greater than or equal to the allowed minimum value and less than or equal to the allowed maximum value.
 */
export function Range(minValue: number, maxValue: number, validationOptions?: ValidationOptions): PropertyDecorator {
  return ValidateBy(
    {
      name: RANGE,
      constraints: [minValue, maxValue],
      validator: {
        validate: (value, args): boolean => range(value, args?.constraints[0], args?.constraints[1]),
        defaultMessage: buildMessage(
          eachPrefix => eachPrefix + '$property must be greater than or equal to $constraint1 and less than or equal to $constraint2',
          validationOptions
        ),
      },
    },
    validationOptions
  );
}

It would simplify code for typical use case like this:

@Min(1)
@Max(10)
priority: number

The same conditions with new decorator would look like this:

@Range(1, 10)
priority: number
@rastorc3v rastorc3v added flag: needs discussion Issues which needs discussion before implementation. type: feature Issues related to new features. labels Nov 3, 2024
@bzhn
Copy link

bzhn commented Nov 7, 2024

Take into account that there may be conflicts with using Range as a decorator name, as shown in the screenshots. This name is already associated with the Range interface in the DOM API, which could lead to confusion or potential conflicts.

image
image

Possible alternatives:

@ValueRange()
@MinMaxRange()
@Between()
@WithinRange()

More on Range:

interface Range
A fragment of a document that can contain nodes and parts of text nodes.

https://developer.mozilla.org/en-US/docs/Web/API/Range

@rastorc3v
Copy link
Author

Have nothing against name changing suggestion from @bzhn 👍. Will add another suggestion: @NumRange

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
flag: needs discussion Issues which needs discussion before implementation. type: feature Issues related to new features.
Development

No branches or pull requests

2 participants