React TypeScript组件:限制仅传入onAction或onDoubleAction其一Props
要实现onAction和onDoubleAction只能二选一的TypeScript约束,可以通过联合类型+never类型构造互斥属性类型,具体步骤如下:
1. 定义基础按钮属性
先提取按钮的公共属性,比如子元素、禁用状态等:
import React from 'react'; type BaseButtonProps = { children: React.ReactNode; disabled?: boolean; // 可添加其他公共属性,比如className、style等 };
2. 构造互斥的回调属性类型
创建两个分支类型,分别限制只能存在其中一个回调,同时将另一个回调设为never(表示该属性不允许被赋值):
type SingleActionProps = // 仅允许传入onAction,onDoubleAction必须为undefined或不传入 | { onAction: (e: React.MouseEvent<HTMLButtonElement>) => void; onDoubleAction?: never } // 仅允许传入onDoubleAction,onAction必须为undefined或不传入 | { onDoubleAction: (e: React.MouseEvent<HTMLButtonElement>) => void; onAction?: never };
3. 合并得到最终的ButtonProps
将基础属性和互斥回调属性交叉合并:
type ButtonProps = BaseButtonProps & SingleActionProps;
4. 实现Button组件
基于最终的类型定义编写组件:
const Button: React.FC<ButtonProps> = ({ children, disabled = false, onAction, onDoubleAction }) => { return ( <button disabled={disabled} onClick={onAction} onDoubleClick={onDoubleAction} style={{ padding: '8px 16px', cursor: disabled ? 'not-allowed' : 'pointer' }} > {children} </button> ); };
5. 测试约束效果
合法用法(仅传入单个回调):
// 仅点击回调 <Button onAction={(e) => console.log('点击事件', e)}>点击我</Button> // 仅双击回调 <Button onDoubleAction={(e) => console.log('双击事件', e)}>双击我</Button> // 无回调(也允许) <Button>普通按钮</Button>非法用法(同时传入两个回调):
// TypeScript会抛出错误:类型“(e: MouseEvent<HTMLButtonElement, MouseEvent>) => void”的参数不能赋给类型“undefined”的参数 <Button onAction={(e) => console.log('点击')} onDoubleAction={(e) => console.log('双击')} > 错误按钮 </Button>
原理说明
通过never类型限制互斥属性的赋值,当同时传入两个回调时,TypeScript会检测到属性值与never类型冲突,从而抛出明确的错误提示,达到“二选一”的约束目的。
内容的提问来源于stack exchange,提问作者Husdady
相关产品推荐
相关产品推荐

