Skip to content

feature(SatisfyAny): add a validator to ensure given value satisfies any of constraint functions, in order to validate Union Type, etc #2575

Open
@qwertycxz

Description

@qwertycxz

Description

To validate a union type, the user has to make Custom validation, which is not very convenient for such a commonly used type.

Proposed solution

I wrote a SatisfyAny.ts. It works well:

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

export const SATISFY_ANY = 'satisfyAny';

/**
 * Checks if given value satisfies any of the validators.
 */
export function satisfyAny(value: unknown, validators: readonly ((value: unknown) => boolean)[]): boolean {
  return validators.some(validator => validator(value));
}

/**
 * Checks if given value satisfie any of the validators.
 */
export function SatisfyAny(values: readonly ((value: unknown) => boolean)[], validationOptions?: ValidationOptions): PropertyDecorator {
  return ValidateBy(
    {
      name: SATISFY_ANY,
      constraints: [values],
      validator: {
        validate: (value, args): boolean => satisfyAny(value, args?.constraints[0]),
        defaultMessage: buildMessage(
          eachPrefix => eachPrefix + '$property must satisfy one of the following validators: $constraint1',
          validationOptions
        ),
      },
    },
    validationOptions
  );
}

Usage

import {
    isBoolean,
    IsNotEmpty,
    isString,
    SatisfyAny,
} from "class-validator";

class LanguageConfig {
    @SatisfyAny([isBoolean, isString])
    @IsNotEmpty()
    shell!: boolean | string;
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    flag: needs discussionIssues which needs discussion before implementation.type: featureIssues related to new features.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions