如何在TypeScript中通过映射类型移除非函数属性
移除TypeScript类型中的非函数属性
看起来你想要的是彻底移除类型里的非函数属性,而不是仅仅把它们的类型改成never对吧?你的当前实现只是把非函数属性标记为never,但这些键依然存在于类型中——咱们来调整一下类型定义,就能实现真正的移除效果了。
解决方案(TypeScript 4.1+)
直接在映射类型中使用as子句过滤掉非函数属性的键:
class A { x = 0; y = 0; visible = false; render() { } } // 修改后的类型定义 type RemoveProperties<T> = { readonly [P in keyof T as T[P] extends Function ? P : never]: T[P]; }; var a = new A() as RemoveProperties<A>; a.render(); // ✅ 完全正常调用 a.visible; // ❌ 报错:属性'visible'不存在于类型'RemoveProperties<A>'上 a.x; // ❌ 报错:属性'x'不存在
原理说明
这里用到了TypeScript 4.1引入的映射类型过滤(as子句):
- 遍历目标类型
T的每个键P - 判断该键对应的属性值
T[P]是否为Function类型 - 如果是函数类型,就保留这个键;否则返回
never,该键会被自动从最终类型中移除
兼容旧版本TypeScript(<4.1)
如果你的项目还在使用较低版本的TypeScript,可以用Pick结合条件类型来实现相同效果:
// 先提取所有函数类型的键 type FunctionKeys<T> = { [P in keyof T]: T[P] extends Function ? P : never }[keyof T]; // 再保留这些键对应的属性 type RemoveProperties<T> = Pick<T, FunctionKeys<T>>;
这个写法的逻辑是先找出所有值为函数类型的键,再用Pick从原类型中只保留这些键的属性,最终效果和上面的方案一致。
内容的提问来源于stack exchange,提问作者Wander Wang
相关产品推荐
相关产品推荐

