如何从TypeScript函数类型中省略指定属性?
从带属性的函数类型中省略指定属性
问题原因
你遇到的问题是因为TypeScript内置的Omit工具类型仅针对对象类型的可枚举属性,而函数的调用签名(比如<T>(result: T): void和(...results: any[]): void)不属于keyof操作符能捕获的范畴。
查看Omit的默认实现就能明白:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
对于你的原类型,keyof OriginalType只会返回"error"(只有对象属性会被keyof识别),所以Exclude<keyof T, 'error'>得到的是空集合,最终Pick<T, never>返回{}。
解决方案
需要自定义一个工具类型,同时保留函数的调用签名和省略指定的对象属性。可以通过交叉类型结合条件类型实现:
// 自定义工具类型:保留函数调用签名,省略指定对象属性 type OmitPropertyFromCallable<T, K extends PropertyKey> = // 提取原类型的函数调用签名部分 (T extends (...args: any[]) => any ? T : never) // 交叉上省略了指定属性的对象部分 & Omit<T, K>; // 原类型 type OriginalType = { <T>(result: T): void (...results: any[]): void; error(...errors: any[]): void; }; // 使用自定义工具类型省略error属性 type OmitError = OmitPropertyFromCallable<OriginalType, 'error'>;
此时OmitError的类型就符合你的预期:
{ <T>(result: T): void; (...results: any[]): void; }
原理说明
- 条件类型
T extends (...args: any[]) => any ? T : never会保留原类型中的所有函数调用签名(包括重载)。 Omit<T, K>负责移除原类型中指定的对象属性。- 通过交叉类型
&将两部分合并,得到同时保留调用签名和剩余对象属性的类型。
内容的提问来源于stack exchange,提问作者TrevTheDev
相关产品推荐
相关产品推荐

