n4s
Version:
typed schema validation version of enforce
67 lines (59 loc) • 2.06 kB
text/typescript
import type { CB, DropFirst } from 'vest-utils';
import type { FirstParam } from './eager/typeUtils';
import { RuleRunReturn } from './utils/RuleRunReturn';
/**
* Global namespace for n4s custom rules.
* Users should extend EnforceMatchers with value-first rule signatures.
* These will be used to type both eager (value-first drop) and lazy (builder) APIs.
*
* Each rule is a function whose FIRST parameter is the value being validated.
* The function should return a boolean or a RuleRunReturn<T>.
*
* Example:
* declare global {
* namespace n4s {
* interface EnforceMatchers {
* isPositive: (value: number) => boolean;
* isBetween: (value: number, min: number, max: number) => boolean;
* }
* }
* }
*/
declare global {
namespace n4s {
interface EnforceMatchers {}
}
}
export type EnforceMatchers = n4s.EnforceMatchers;
// Note: We don't augment RuleInstance here with mapped types, because TS disallows
// interfaces extending mapped/conditional types. Instead, eager.ts and lazy.ts
// each map n4s.EnforceMatchers into their respective APIs explicitly.
/**
* Base type for mapping custom matcher functions.
* Drops the first parameter (value) and maps remaining args.
*/
export type CustomMatcherArgs<K extends keyof n4s.EnforceMatchers> = DropFirst<
Parameters<Extract<n4s.EnforceMatchers[K], CB>>
>;
export type EnforceCustomMatcher<F extends CB> = (
...args: CustomMatcherArgs<F extends keyof n4s.EnforceMatchers ? F : never>
) => boolean | RuleRunReturn<any>;
/**
* Maps custom rules to eager API signatures (drops the value parameter).
* Only includes rules where T matches the first parameter type.
*/
export type TCustomRules<T, A, S> = {
[K in keyof n4s.EnforceMatchers as T extends FirstParam<
n4s.EnforceMatchers[K]
>
? K
: never]: (
...args: CustomMatcherArgs<K>
) => import('./eager').EnforceEagerReturn<T, A, S>;
};
export type WidenFirstParam<F, T> = F extends (
arg: any,
...rest: infer R
) => infer Ret
? (arg: T, ...rest: R) => Ret
: never;