【问题标题】:Next arguments of function definition depending on first argument函数定义的下一个参数取决于第一个参数
【发布时间】:2022-11-17 05:55:11
【问题描述】:

考虑具有不同参数的简单函数列表:

const fns = {
  isValidDate: (input: string, min?: Date, max?: Date): boolean => {
     // ...
     return true;
  },

  isValidOption: (input: string, options: string[]): boolean => {
     // ...
     return true;
  },

};

它们都返回相同的类型(bool);

然后是另一个应该调用上述任何函数的函数:

function validateField(where: string, fn: keyof typeof fns, ...args: any[]){
   // ...
   return fns[fn](...args);
}

如何使 args 反映所选 fn 的参数?

例如:

validateField("test", "isValidDate", new Date()); // should be ok 
validateField("test", "isValidDate", 123); // should fail

并在 vscode 提示中显示参数,就像在普通函数上一样。

我知道我需要为每个 fn 创建 validateField 的重载,但是如何使用类型定义或其他东西来做到这一点......而不必手动定义每个重载并使用这些参数编写重复代码

【问题讨论】:

  • this approach 是否满足您的需求?根本问题是缺乏对相关联盟按照 ms/TS#30581 中的要求,推荐的解决方案是使用泛型进行类型重构,如 ms/TS#47109 中所述。如果这完全解决了您的问题,那么我可以写一个答案来解释;否则,我错过了什么? (如果您回复,请通过@jcalz 联系我)
  • 作为旁注,使用 OOP 而不是函数会容易得多:例如 class DateValidator implements Validatorclass OptionValidator... 等,然后只是 validate(input, validators: Validator[])
  • @jcalz 它似乎确实按预期工作!你应该把它作为答案发布 :P

标签: javascript typescript overloading


【解决方案1】:

要解决您的问题,您可以使用 Generic 类型获取函数类型,然后使用它获取参数的类型

function validateField<key extends keyof typeof fns>(where: string, fn: key, ...options: Parameters<typeof fns[key]>): boolean {
  const fnToCall = fns[fn];
  return fnToCall(...options);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 2018-03-22
    • 2014-04-05
    • 2021-12-20
    • 1970-01-01
    • 1970-01-01
    • 2015-11-29
    相关资源
    最近更新 更多