You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript中如何结合infer合并校验器类型并实现互斥逻辑?

解决方案与优化方案

问题分析

原代码的核心问题在于规则组移除逻辑的条件分支过于局限,仅能处理元组中特定位置的规则组,导致调用中间位置的规则组方法后,无法正确合并剩余的所有规则组。同时,原逻辑未妥善处理required/noRequired的互斥需求(调用其中一个后需同时禁用两个方法)。

修复后的代码

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 RemoveFromTuple<T extends any[], U> = T extends [infer First, ...infer Rest]
  ? First extends U
    ? RemoveFromTuple<Rest, U>
    : [First, ...RemoveFromTuple<Rest, U>]
  : [];

// 包装单个规则组的方法,调用后移除当前规则组并合并剩余规则
type CoFormRuleWarpKeys<T, Raw extends any[]> = {
  [Key in keyof T]: T[Key] extends (...args: infer P) => any
    ? (...args: P) => CoFormRuleMerge<RemoveFromTuple<Raw, T>, Raw>
    : InvalideFunctionParams;
};

// 递归合并多个规则组
type CoFormRuleMerge<T extends any[], Raw extends any[]> = T extends [infer First, ...infer Rest]
  ? CoFormRuleWarpKeys<First, Raw> & CoFormRuleMerge<Rest, Raw>
  : {};

// 入口类型:合并传入的规则组元组
type CoFormRuleMergeCall<T extends any[]> = CoFormRuleMerge<T, T>;

const a: CoFormRuleMergeCall<[
  CoFormRuleRequire,
  CoFormRuleSize,
  CoFormRuleClarity
]> = {} as any;

// 示例1:调用between后,返回CoFormRuleRequire & CoFormRuleClarity
const b = a.between(1, 2);

// 示例2:调用between后再调用required,返回CoFormRuleClarity
const c = a.between(1, 2).required();

// 互斥逻辑测试:调用required后,无法再调用required/noRequired
const d = a.required();
// d的类型为CoFormRuleSize & CoFormRuleClarity,无required/noRequired方法

关键修复点

  1. 通用元组移除工具:新增RemoveFromTuple类型,能够从任意元组中移除指定类型的元素,替代原代码中局限的位置匹配逻辑,确保不管规则组在元组的哪个位置,调用后都能正确移除。
  2. 简化规则合并逻辑:重写CoFormRuleWarpKeys和CoFormRuleMerge,调用任意规则组的方法后,自动移除该规则组并合并剩余所有规则组,天然满足required/noRequired的互斥需求(调用其中一个方法后,整个CoFormRuleRequire规则组被移除,两个方法都不可再调用)。

优化方案

  1. 支持细粒度互斥:如果需要规则组内部分方法互斥(而非整个规则组),可新增标记类型定义互斥方法组,例如:

    // 定义互斥方法标记
    type MutexMethods<T extends string[]> = { __mutexMethods: T };
    // 修改CoFormRuleRequire,标记互斥方法
    type CoFormRuleRequire = {
      required(): any;
      noRequired(): any;
    } & MutexMethods<["required", "noRequired"]>;
    

    再扩展RemoveFromTuple逻辑,针对标记的互斥方法单独处理,调用其中一个后仅移除该组内的方法,而非整个规则组。

  2. 增强参数校验:通过条件类型强制方法参数必填,避免运行时参数错误:

    type CoFormRuleWarpKeys<T, Raw extends any[]> = {
      [Key in keyof T]: T[Key] extends (...args: infer P) => any
        ? P extends []
          ? () => CoFormRuleMerge<RemoveFromTuple<Raw, T>, Raw>
          : (...args: P) => CoFormRuleMerge<RemoveFromTuple<Raw, T>, Raw>
        : InvalideFunctionParams;
    };
    
  3. 类型推导优化:添加泛型约束,确保传入CoFormRuleMergeCall的元组仅包含规则组类型,避免非法类型传入:

    type RuleGroup = Record<string, (...args: any[]) => any>;
    type CoFormRuleMergeCall<T extends RuleGroup[]> = CoFormRuleMerge<T, T>;
    

内容的提问来源于stack exchange,提问作者shock cure

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 01:02:56