为何TypeScript中filter1的类型参数设计优于filter2?
为什么filter1比filter2的设计更优?
核心结论:filter2的额外类型参数Func完全冗余,既没有带来额外价值,还会给调用者和维护者增加不必要的负担,下面具体拆解问题:
1. 手动指定类型参数时的额外负担(对应文档描述的核心点)
当调用者需要手动指定类型参数时(比如自动推断不符合预期,或是想明确约束类型),filter1只需要指定数组元素的类型Type,但filter2必须同时指定Type和Func两个类型参数——而Func的类型其实完全可以由Type推导出来,根本不需要调用者手动声明。
实际调用对比:
// filter1:只需要指定元素类型number,简洁直观 filter1<number>([1, 2, 3], n => n > 1); // filter2:必须同时指定Type和Func,否则TS会抛出类型参数数量不足的错误 // 错误写法: filter2<number>([1, 2, 3], n => n > 1); // 正确但冗余的写法: filter2<number, (arg: number) => boolean>([1, 2, 3], n => n > 1);
这就是文档所说的「希望指定类型参数的调用者必须手动指定额外的类型参数」——调用者本来只关心数组元素的类型,却被迫额外声明一个完全没必要的函数类型,大幅增加了调用成本。
2. 类型参数冗余,徒增签名复杂度
filter2的Func类型参数没有任何实际作用:
- 它的约束
extends (arg: Type) => boolean,和filter1里直接写(arg: Type) => boolean的效果完全一致; - 函数返回值都是
Type[],没有因为Func的存在获得更精确的类型; - TypeScript完全可以自动推断出
Func的类型,不需要手动声明这个参数。
额外的类型参数只会让函数签名更难读,让其他开发者需要花更多时间理解这个参数的意义——而实际上它没有任何价值。
3. 违背「最少必要类型参数」的设计原则
TypeScript类型参数的设计原则是:只保留那些无法通过函数参数推导出来的类型信息。filter1的Type是必要的(它描述了数组元素的类型,无法从其他参数推导),但filter2的Func完全可以通过Type和func参数的类型推导出来,属于完全冗余的设计。
内容的提问来源于stack exchange,提问作者Black Wind
相关产品推荐
相关产品推荐

