TypeScript中带泛型的回调函数重载实现方法
如何在TypeScript中声明支持可变数量泛型参数的回调类型
问题原因分析
你最初用重载接口声明CustomFn的方式之所以失败,是因为TypeScript对函数重载的赋值有严格要求:赋值的函数必须兼容所有重载签名。比如双参数函数无法被赋值给原CustomFn,因为当调用它时只传一个参数,该函数会因参数不足报错,不符合单参数重载的调用要求。
正确实现方式:使用联合类型
通过联合类型,我们可以将不同参数数量的泛型函数类型组合起来,只要赋值的函数匹配其中任意一个分支即可,完美适配你的验证规则场景。
1. 声明CustomFn联合类型
type CustomFn = | (<T>(value: T) => boolean) | (<T, U>(value: T, param: U) => boolean) | (<T, U, V>(value: T, param1: U, param2: V) => boolean);
这里明确定义了1个、2个、3个参数的泛型函数分支,每个分支的参数类型可以自由指定,最终都返回boolean。
2. 适配验证规则场景
将ValidationRule接口和规则数组调整为以下形式(修正原代码中数组类型的错误):
export interface ValidationRule { name: string; validator: CustomFn; } const validationRules: ValidationRule[] = [ { name: 'required', validator: (s: string) => { return s != null; } }, { name: 'greaterThan', validator: (value: number, max: number) => { return value > max; } }, { name: 'range', validator: (value: number, min: number, max: number) => { return value >= min && value <= max; } } ];
可维护性扩展
如果后续需要支持更多参数的验证函数,只需在CustomFn的联合类型中添加新的分支即可,比如4个参数的函数:
type CustomFn = | (<T>(value: T) => boolean) | (<T, U>(value: T, param: U) => boolean) | (<T, U, V>(value: T, param1: U, param2: V) => boolean) | (<T, U, V, W>(value: T, param1: U, param2: V, param3: W) => boolean);
内容的提问来源于stack exchange,提问作者Michael Kang
相关产品推荐
相关产品推荐

