如何在 typescript 中合并 ...infer 和其他一些类型

问题描述 投票:0回答:0

我正在使用打字稿在验证器上进行类型排列。 比如required、noRequired是互斥逻辑。 如果使用 required ,则 required 和 noRequired 都不需要再次使用。 您可以通过复制以下代码并在 vs 代码中使用 b 对象来调试它。

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

非常感谢解决方案和优化方案

typescript type-inference
© www.soinside.com 2019 - 2024. All rights reserved.