React中根据多组件Props设置onClose为必填项的最优方案
解决ModalProps中onClose条件必填的问题
你之前的写法失效,是因为BaseModalProps不包含hasCloseIcon、closeOnOutsideClick、dismissAfter这三个属性,导致条件判断永远不成立,OnCloseProp始终是可选的onClose类型,自然无法触发必填校验。
下面提供两种简洁的解决方案,无需编写8种组合:
方案一:拆分场景的联合类型
将ModalProps拆分为无需强制onClose和必须强制onClose两种场景的联合类型,逻辑清晰且易于维护:
type BaseModalProps = { isOpen: boolean; content: string; }; // 场景1:所有触发条件都不满足,onClose可选 type ModalWithoutOnClose = BaseModalProps & { hasCloseIcon?: false; closeOnOutsideClick?: false; dismissAfter?: never; onClose?: () => void; }; // 场景2:任意一个触发条件满足,onClose必填 type ModalWithOnClose = BaseModalProps & ( | { hasCloseIcon: true; onClose: () => void } | { closeOnOutsideClick: true; onClose: () => void } | { dismissAfter: number; onClose: () => void } ) & { // 允许其他非触发条件保持原有可选性 hasCloseIcon?: boolean; closeOnOutsideClick?: boolean; dismissAfter?: number; }; type ModalProps = ModalWithoutOnClose | ModalWithOnClose;
测试验证:
- 触发条件生效时,必须传入
onClose:
// ❌ 报错:缺少必填属性onClose const invalidModal: ModalProps = { isOpen: true, content: '测试内容', hasCloseIcon: true }; // ✅ 正常通过 const validModal: ModalProps = { isOpen: true, content: '测试内容', hasCloseIcon: true, onClose: () => {} };
- 无触发条件时,
onClose可选:
// ✅ 正常通过 const optionalModal: ModalProps = { isOpen: true, content: '测试内容' };
方案二:泛型+条件类型
利用泛型的类型推断能力,直接通过条件判断动态设置onClose的必填性,写法更简洁:
type BaseModalProps = { isOpen: boolean; content: string; hasCloseIcon?: boolean; closeOnOutsideClick?: boolean; dismissAfter?: number; }; type ModalProps<T extends BaseModalProps = BaseModalProps> = T extends ( | { hasCloseIcon: true } | { closeOnOutsideClick: true } | { dismissAfter: number } ) ? Omit<T, 'onClose'> & { onClose: () => void } : T;
测试验证:
// ❌ 报错:缺少必填属性onClose const invalid: ModalProps = { isOpen: true, content: '测试内容', dismissAfter: 3000 }; // ✅ 正常通过 const valid: ModalProps = { isOpen: true, content: '测试内容', dismissAfter: 3000, onClose: () => {} }; // ✅ 正常通过(无触发条件,onClose可选) const optional: ModalProps = { isOpen: true, content: '测试内容' };
内容的提问来源于stack exchange,提问作者ASJ
相关产品推荐
相关产品推荐

