如何让TypeScript接口属性值依赖其他属性实现差异化限制?
解决Toast组件根据尺寸约束duration取值的问题
要实现根据smallSize的取值约束duration的可选范围,你可以用TypeScript的区分联合类型(Discriminated Unions),让类型系统自动校验属性间的依赖关系,具体实现如下:
1. 拆分定义两种场景的接口
先分别定义smallSize为true和false时的属性结构,明确各自允许的duration取值:
// 小尺寸Toast的属性 interface ISmallToast { id: string; open: boolean; smallSize: true; title?: string; content: string; duration?: 4000 | 5000 | 6000 | null; } // 常规尺寸Toast的属性 interface IRegularToast { id: string; open: boolean; smallSize?: false; title?: string; content: string; duration?: 6000 | 7000 | 8000 | null; }
2. 合并为联合类型作为组件Props
把两个接口合并成联合类型,作为Toast组件的props类型:
type IToastProps = ISmallToast | IRegularToast; const Toast = (props: IToastProps): JSX.Element => { const { id, open = false, smallSize = false, title, content = "", duration = null, } = props; // 后续逻辑中TypeScript会自动根据smallSize收窄duration的类型 if (smallSize) { // 此处duration类型为 4000 | 5000 | 6000 | null } else { // 此处duration类型为 6000 | 7000 | 8000 | null } return <></>; };
3. 使用时的类型校验效果
当使用者传入smallSize: true时,TypeScript会自动限制duration只能选4000/5000/6000/null;smallSize: false或不传入时,duration只能选6000/7000/8000/null,不符合规则的取值会直接触发类型报错:
// 错误:smallSize为true时,duration不能传7000 <Toast id="1" open={true} smallSize={true} content="test" duration={7000} /> // 错误:smallSize为false时,duration不能传4000 <Toast id="2" open={true} smallSize={false} content="test" duration={4000} />
内容的提问来源于stack exchange,提问作者Judoboy Alex
相关产品推荐
相关产品推荐

