TypeScript扩展接口时如何排除父级mysql.RowDataPacket属性
问题原因
你原来的写法之所以会继承mysql.RowDataPacket的属性,是因为Omit<MyDTO, 'id'>处理的是MyDTO合并后的完整类型(包含所有继承来的属性),所以会把RowDataPacket的字段也带进来。
解决方案
这里提供两种可行的实现方式,可根据项目改动成本选择:
方式1:抽离基础字段(推荐,可维护性最高)
先把业务自定义的字段抽离为独立的基础接口,原有查询用的MyDTO和新增的创建用DTO分别基于这个基础接口扩展:
// 抽离所有业务自定义的基础字段,无任何外部继承 export interface MyBaseDTO { id: number; name: string; // 其他自定义字段 } // 原有查询用的DTO,继续继承RowDataPacket export interface MyDTO extends MyBaseDTO, mysql.RowDataPacket {} // 创建用DTO,直接从基础字段排除id即可,完全不会涉及RowDataPacket的属性 export interface CreateMyDTO extends Omit<MyBaseDTO, 'id'> {}
方式2:手动Pick指定字段(无需改动原有MyDTO定义)
如果项目改动成本高,不想调整原有MyDTO的继承结构,可以直接用Pick精准选择需要的自定义字段,这样会自动排除掉继承自mysql.RowDataPacket的所有属性:
// 只选择你在MyDTO里自定义的、需要保留的字段即可 export interface CreateMyDTO extends Pick<MyDTO, 'name' /* 其他需要的自定义字段 */> {}
补充说明:TypeScript的类型系统在编译后会被擦除,没有内置的工具类型可以自动区分接口的「自有声明属性」和「继承来的属性」,所以没有完全自动的方案可以不声明字段就过滤掉继承属性,以上两种是目前业界最常用的实现方案。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

