如何根据actionLabel值动态修改TypeScript接口中duration属性取值?
实现actionLabel非空时duration为null的Toast类型约束
要实现当actionLabel.length > 0时,IToastSmall和IToastLarge的duration必须为null,可以通过TypeScript的条件类型+交叉类型构建约束,确保类型之间的依赖关系。
具体实现代码
interface IToastBase { id: string; open: boolean; title?: string; content: string; actionLabel?: string; } // 带actionLabel时的约束:强制duration为null type ToastWithAction<T extends { smallSize?: boolean }> = IToastBase & { actionLabel: string } & T & { duration: null }; // 不带actionLabel时的约束:保留原有duration数值选项 type ToastWithoutAction<T extends { smallSize?: boolean; duration: number }> = IToastBase & { actionLabel?: never } & T; // 组合Small Toast的两种场景 type IToastSmall = ToastWithAction<{ smallSize?: true }> | ToastWithoutAction<{ smallSize?: true; duration: 4000 | 5000 | 6000 }>; // 组合Large Toast的两种场景 type IToastLarge = ToastWithAction<{ smallSize?: false }> | ToastWithoutAction<{ smallSize?: false; duration: 6000 | 7000 | 8000 }>; type IToast = IToastSmall | IToastLarge;
代码说明
ToastWithAction:当actionLabel为必填的非空字符串时,交叉类型强制duration只能是null,同时保留smallSize的可选性。ToastWithoutAction:当actionLabel不存在(或设为never避免传入空字符串)时,沿用原有的duration数值范围约束。- 最终通过联合类型将两种场景合并,确保类型检查时的合法性。
验证示例
// 合法:存在actionLabel,duration为null const validWithAction: IToast = { id: "toast-1", open: true, content: "操作成功", actionLabel: "查看详情", duration: null, smallSize: true }; // 合法:无actionLabel,使用指定duration数值 const validWithoutAction: IToast = { id: "toast-2", open: true, content: "消息提示", duration: 6000, smallSize: false }; // 非法:存在actionLabel但duration不是null(TypeScript会抛出类型错误) const invalidToast: IToast = { id: "toast-3", open: true, content: "错误提示", actionLabel: "重试", duration: 5000 // 此处类型不匹配,编译器报错 };
内容的提问来源于stack exchange,提问作者Judoboy Alex
相关产品推荐
相关产品推荐

