TypeScript如何将继承多接口的对象拆分为对应各接口的属性集合
TypeScript 的 interface 属于编译期类型,运行时会被完全擦除,没有原生能力直接读取 interface 包含的属性列表,所以要实现无感知拆分,需要先将父接口的属性定义和运行时的值做一次绑定,不需要你手动逐一枚举属性归属。
实现方案
方法1:手动维护属性列表(无第三方依赖)
只需要维护一次属性列表,自动生成对应 interface 类型,后续修改只需要调整列表即可:
// 1. 定义InterfaceA的属性数组,同时生成对应类型 const INTERFACE_A_FIELDS = ['name', 'age', 'gender'] as const type InterfaceA = { [key in typeof INTERFACE_A_FIELDS[number]]: any } // 2. 定义InterfaceB的属性数组,同时生成对应类型 const INTERFACE_B_FIELDS = ['job', 'address', 'phone'] as const type InterfaceB = { [key in typeof INTERFACE_B_FIELDS[number]]: any } // 3. 合并接口正常继承 interface AnB extends InterfaceA, InterfaceB {} // 4. 通用属性提取工具函数 function pickByFieldList<T, K extends keyof T>(target: T, fieldList: readonly K[]): Pick<T, K> { const res = {} as Pick<T, K> fieldList.forEach(field => field in target && (res[field] = target[field])) return res } // 实际使用 const aAndB: AnB = { name: '张三', age: 25, gender: '男', job: '工程师', address: '北京', phone: '13xxxxxxxxx' } // 直接拆分,不需要知晓具体属性 const valuesFromInterfaceA = pickByFieldList(aAndB, INTERFACE_A_FIELDS) const valuesFromInterfaceB = pickByFieldList(aAndB, INTERFACE_B_FIELDS)
方法2:编译期自动提取属性(无需手动维护列表)
如果已经存在定义好的 InterfaceA、InterfaceB 不想修改,可以使用 TypeScript 编译插件自动提取 interface 的属性列表为运行时可用的常量,不需要手动维护字段数组,同样可以实现无感拆分。
内容的提问来源于stack exchange,提问作者Ruben Hamakers
相关产品推荐
相关产品推荐

