如何为泛型超类型参数应用Omit工具函数?特殊组件场景
要实现让ModalBody组件禁止使用tag属性(触发编译错误),同时不影响其他继承自BaseShardsComponent的组件,我们可以通过类型覆盖+接口合并的方式修改你的模块声明,具体方案如下:
declare module 'shards-react' { // 先抽离Base组件的基础props,方便后续操作 type BaseShardsBaseProps = { className?: string; tag?: string | keyof HTMLElementTagNameMap; }; // 保持原有的Base组件定义不变 class BaseShardsComponent<T = {}> extends React.Component<BaseShardsBaseProps & T> {} // 为ModalBody定义专属props:去掉tag的基础props + 自定义泛型扩展 type ModalBodyProps<T = {}> = Omit<BaseShardsBaseProps, 'tag'> & T; // 声明ModalBody组件,继承Base组件 export class ModalBody<T = {}> extends BaseShardsComponent<T> {} // 通过接口合并,让TypeScript识别ModalBody的真实props类型 interface ModalBody<T = {}> extends React.Component<ModalBodyProps<T>> {} }
为什么这样做?
- 抽离基础props:把
BaseShardsComponent的默认props(className和tag)抽成单独的BaseShardsBaseProps类型,让后续的Omit操作更直观,也方便维护。 - 定义ModalBody专属props:使用
Omit<BaseShardsBaseProps, 'tag'>移除tag属性,同时保留泛型T支持自定义扩展props,兼顾灵活性和约束性。 - 接口合并覆盖类型:通过TypeScript的接口合并特性,让
ModalBody组件的props类型指向我们定义的ModalBodyProps,这样TypeScript就会在编译时检查到tag属性不被允许。
效果验证
当你尝试使用tag属性时:
<ModalBody tag={'bjaisd'}></ModalBody>
TypeScript会直接抛出编译错误:
Property 'tag' does not exist on type 'IntrinsicAttributes & ModalBodyProps<{}>'.
而其他继承自BaseShardsComponent的组件(比如你可能有的ModalHeader、ModalFooter等),依然可以正常使用tag属性,完全不受影响。
简化版(如果不想抽离基础props)
如果你觉得抽离基础props太繁琐,也可以直接在Omit中引用BaseShardsComponent的props类型:
declare module 'shards-react' { class BaseShardsComponent<T = {}> extends React.Component<{ className?: string; tag?: string | keyof HTMLElementTagNameMap; } & T> {} export class ModalBody<T = {}> extends BaseShardsComponent<T> {} // 直接通过Omit移除tag属性 interface ModalBody<T = {}> extends React.Component< Omit<Parameters<typeof BaseShardsComponent<T>['props']>[0], 'tag'> > {} }
这个版本效果和上面一致,只是代码更紧凑一些。
内容的提问来源于stack exchange,提问作者Jazzepi
相关产品推荐
相关产品推荐

