n4s
Version:
typed schema validation version of enforce
52 lines (48 loc) • 1.75 kB
text/typescript
import { isNullish } from 'vest-utils';
import { RuleInstance } from '../../utils/RuleInstance';
import { RuleRunReturn } from '../../utils/RuleRunReturn';
/**
* Makes a validation rule optional by allowing null or undefined values to pass.
* If the value is null or undefined, validation passes without running the inner rule.
* Otherwise, the inner rule is executed.
*
* @template T - The value type to validate
* @param value - The value to validate (may be null/undefined)
* @param rule - The RuleInstance to apply if value is not nullish
* @returns RuleRunReturn indicating success or failure
*
* @example
* ```typescript
* // Eager API
* enforce(undefined).optional(enforce.isString()); // passes
* enforce(null).optional(enforce.isString()); // passes
* enforce('hello').optional(enforce.isString()); // passes
* enforce(123).optional(enforce.isString()); // fails
*
* // Lazy API - useful in schemas
* const userSchema = enforce.shape({
* name: enforce.isString(),
* middleName: enforce.optional(enforce.isString()),
* age: enforce.isNumber()
* });
*
* userSchema.test({ name: 'John', age: 30 }); // true (middleName optional)
* userSchema.test({ name: 'John', middleName: null, age: 30 }); // true
* userSchema.test({ name: 'John', middleName: 'Q', age: 30 }); // true
* userSchema.test({ name: 'John', middleName: 123, age: 30 }); // false
* ```
*/
export function optional<T>(
value: T | undefined | null,
rule: any,
): RuleRunReturn<T | undefined | null> {
if (isNullish(value)) {
return RuleRunReturn.Passing(value);
}
return rule.run(value);
}
// Type for optional rule instance
export type OptionalRuleInstance<T> = RuleInstance<
T | undefined | null,
[T | undefined | null]
>;