如何实现传入href/to时Button组件的link属性必填?
解决方案
要实现「传入href或to时,link必须必填;否则link可选」的类型约束,你需要将ButtonProps定义为两种场景的联合类型,而非单纯使用「至少一个必填」的泛型工具。
最终类型定义
import type React from 'react'; // 基础属性集合 type BaseButtonProps = { href?: string; to?: string; link?: React.ElementType; }; // 场景1:不传入href/to,link可选(严格禁止传入href/to) type NonLinkButtonProps = Omit<BaseButtonProps, 'href' | 'to'> & { href?: never; to?: never; }; // 场景2:传入href或to(至少一个),link强制必填 type LinkButtonProps = Pick<BaseButtonProps, 'href' | 'to'> & { link: React.ElementType; }; // 最终的ButtonProps是两种场景的联合 export type ButtonProps = NonLinkButtonProps | LinkButtonProps;
类型说明
- NonLinkButtonProps:限制组件不能接收
href和to属性(传入会直接报错),此时link保持可选状态,对应「普通按钮」场景。 - LinkButtonProps:保留
href和to的可选性(可以传其中一个或两个),但强制要求link必须传入,对应「带跳转的按钮」场景。 - 联合类型会自动帮你做类型校验:当你传入
href或to时,TypeScript会自动匹配到LinkButtonProps,从而要求link必填;如果不传这两个属性,则匹配NonLinkButtonProps,link可选。
验证场景
// 合法:普通按钮,link可选 <Button /> <Button link="a" /> // 报错:传入了href但没传link <Button href="/home" /> // 合法:传入to和link <Button to="/profile" link="a" /> // 合法:同时传入href、to和link <Button href="/home" to="/profile" link="a" />
为什么原方案不适用
你之前用的RequireAtLeastOne工具类型,作用是让指定集合中的至少一个属性必填,但你的需求是「当某几个属性存在时,另一个属性必须存在」,属于条件依赖约束,和「至少一个必填」的逻辑完全不同,所以无法解决你的问题。
内容的提问来源于stack exchange,提问作者Vladyslav Sosnov
相关产品推荐
相关产品推荐

