I'm using typescript to do the type arrangement on validators. For example, required, noRequired are mutually exclusive logic. If required is used, then neither required nor noRequired needs to be used again. You can debug this by copying the following code and using the b object in the vs code.
type CoFormRuleClarity = {
email(): any;
id(): any;
};
type CoFormRuleSize = {
min(num: number): any;
max(num: number): any;
between(min: number, max: number): any;
};
type CoFormRuleRequire = {
required(): any;
noRequired(): any;
};
type InvalideFunctionParams = "Please pass the function parameters";
type CoFormRuleWarpKeys<T, Raw> = {
[Key in keyof T]: T[Key] extends (...args: infer P) => any
? (
...args: P
) => Raw extends [T, ...(infer Right)]
? CoFormRuleMerge<Right, Raw>
: Raw extends [...(infer Left), T]
? CoFormRuleMerge<Left, Raw>
: Raw extends [
infer Left1,
...(infer Left2),
T,
...(infer Right1),
infer Right2
]
// the principal part in there
? CoFormRuleMerge<[Left1, ...Left2, ...Right1, Right2], Raw>
: InvalideFunctionParams
: InvalideFunctionParams;
};
type CoFormRuleMerge<T, Raw> = T extends [infer Left, ...(infer Right)]
? CoFormRuleWarpKeys<Left, Raw> & CoFormRuleMerge<Right, Raw>
: T extends [infer Left]
? CoFormRuleWarpKeys<Left, Raw>
: T extends [infer Left, infer Right]
? CoFormRuleWarpKeys<Left, Raw> & CoFormRuleWarpKeys<Right, Raw>
: {};
type CoFormRuleMergeCall<T extends unknown[]> = CoFormRuleMerge<T, T>;
const a: CoFormRuleMergeCall<[
CoFormRuleRequire,
CoFormRuleSize,
CoFormRuleClarity
]> = {} as any;
// example 1
const b = a.between(1, 2);
// b. current: CoFormRuleRequire
// b. expect: CoFormRuleRequire & CoFormRuleClarity
// example 2
const c = a.between(1, 2).required();
// b. current: CoFormRuleSize & CoFormRuleClarity
// b. expect: CoFormRuleClarity
thank you very much for the solution and the optimization solution.