如何在TypeScript中根据接口动态过滤对象多余属性?
TypeScript 通用对象适配接口方案(移除未定义属性)
在TypeScript中,接口仅存在于编译阶段,运行时无法直接读取其属性信息。要实现移除对象中接口未定义属性的通用功能,可采用以下两种方案:
方案一:手动维护接口属性列表(类型安全最高)
先定义目标接口及对应的属性键数组,再通过通用函数过滤对象:
// 定义目标接口 interface Item { a: number; b: number; } // 手动维护与接口匹配的属性键数组(需同步更新) const ItemKeys = ['a', 'b'] as const; /** * 通用对象过滤函数 * @param obj 待过滤的任意类型对象 * @param keys 目标接口的属性键列表 * @returns 仅包含指定属性的对象 */ function filterObject<T, K extends keyof T>(obj: any, keys: readonly K[]): Pick<T, K> { return keys.reduce((acc, key) => { if (obj.hasOwnProperty(key)) { acc[key] = obj[key]; } return acc; }, {} as Pick<T, K>); } // 使用示例 const item: any = { a: 1, b: 2, c: 3 }; const filteredItem: Item = filterObject<Item, typeof ItemKeys[number]>(item, ItemKeys); console.log(filteredItem); // 输出: { a: 1, b: 2 }
方案二:用类替代接口(无需手动维护属性)
利用类在运行时存在的特性,通过类实例获取属性列表,省去手动维护属性数组的步骤:
// 用类替代接口(类成员需用!断言或初始化值) class Item { a!: number; b!: number; } /** * 根据类过滤对象的通用函数 * @param obj 待过滤的任意类型对象 * @param cls 目标类(替代接口) * @returns 适配类结构的对象 */ function filterByClass<T>(obj: any, cls: new () => T): T { const validKeys = Object.keys(new cls()) as Array<keyof T>; return validKeys.reduce((acc, key) => { if (obj.hasOwnProperty(key)) { acc[key] = obj[key]; } return acc; }, {} as T); } // 使用示例 const item: any = { a: 1, b: 2, c: 3 }; const filteredItem = filterByClass(item, Item); console.log(filteredItem); // 输出: { a: 1, b: 2 }
注意事项
- 方案一需手动同步接口与属性数组,适合接口结构稳定的场景,类型校验最严格。
- 方案二中,类的属性若仅声明类型未初始化,需用
!非空断言,否则Object.keys无法获取到属性名。 - 两种方案均为通用实现,可适配任意接口/类结构,无需针对特定对象硬编码过滤逻辑。
内容的提问来源于stack exchange,提问作者Yahli Gitzi
相关产品推荐
相关产品推荐

