TypeScript中如何给接收含共同属性的不同类型的函数标注类型
TypeScript 带约束泛型实现保留原类型的过滤函数
假设我有两个类型,二者拥有同一个属性myProp:
type TypeA = { myProp: number; propA: string; } type TypeB = { myProp: number; propB: string; }
我需要创建一个topMyProp函数,支持传入TypeA或者TypeB的数组,返回myProp值高于指定阈值的项列表。原有实现如下(注:原代码存在逻辑笔误,判断条件应为val.myProp > threshold,以下实现已修正):
function topMyProp(items: any[], threshold: number) { return items.reduce((acc, val) => { if (val.myProp > threshold) acc.push(val); return acc; }, []) }
这段代码可正常运行,但使用any丢失了TypeA和TypeB的类型信息,无法获得后续类型提示和校验。
尝试过的两种方案均存在缺陷:
- 无约束泛型写法:
function topMyProp<T>(items: T[], threshold: number)
无法约束泛型T必须包含myProp属性,调用时没有类型检查,容易出现属性不存在的运行时错误。
- 固定结构入参写法:
function topMyProp(items: {myProp: number}[], threshold: number)
返回值类型被固定为{myProp: number}[],丢失了入参原本TypeA/TypeB的额外属性的类型信息。
正确实现方案
通过带约束的泛型即可同时满足类型校验和保留原类型的需求,实现如下:
function topMyProp<T extends {myProp: number}>(items: T[], threshold: number) { return items.reduce((acc, val) => { if (val.myProp > threshold) acc.push(val); return acc; }, [] as T[]) }
实现说明
T extends {myProp: number}对泛型参数做约束,保证所有传入的数组项都必须携带类型为数字的myProp属性,调用时会自动校验入参合法性- 泛型
T会自动继承传入数组的完整类型,不管是TypeA还是TypeB都能完整保留所有属性的类型信息 - 初始值
[] as T[]显式声明累加器的类型为T的数组,保证返回值类型和入参数组项的类型完全一致,不需要额外做类型转换
内容的提问来源于stack exchange,提问作者Picci
相关产品推荐
相关产品推荐

