TypeScript如何泛型实现仅允许单个属性的组件Props类型?
通用化实现单属性排他的Drawer组件Props类型
你当前的写法虽然能实现需求,但当属性数量增多时,手动编写每个属性的组合会非常繁琐且容易出错。可以通过TypeScript的映射类型和分布式条件类型实现通用化的类型定义,只需维护属性名列表即可自动生成对应的排他类型。
实现步骤
1. 定义所有可选的属性名联合类型
先把需要支持的Drawer属性名统一放在一个联合类型里,后续扩展属性只需要修改这里:
// 所有支持的Drawer属性名,新增属性直接加在这里即可 type DrawerKeys = 'volunteer' | 'rescues' | 'map';
2. 编写通用的排他属性工具类型
这个工具类型会接收属性名联合类型,自动生成「仅允许其中一个属性为boolean,其余属性必须为never」的联合类型:
type ExclusiveSingleProp<T extends string> = { // 遍历每个属性名K [K in T]: // 生成当前属性K为必填boolean的类型 { [Key in K]: boolean } // 交叉其余属性为可选never的类型(禁止传入) & { [Key in Exclude<T, K>]?: never } // 取出映射后的所有值,组成联合类型 }[T];
3. 生成最终的DrawerProps类型
用上面的工具类型结合DrawerKeys,就能得到通用化的Props类型:
type DrawerTypes = ExclusiveSingleProp<DrawerKeys>;
效果验证
- 合法用法:
<Drawer volunteer />、<Drawer rescues />、<Drawer map /> - 非法用法:
<Drawer volunteer rescues />(此时rescues被限制为never类型,无法传入boolean值)
扩展属性
如果后续需要新增属性(比如profile),只需要修改DrawerKeys即可:
type DrawerKeys = 'volunteer' | 'rescues' | 'map' | 'profile'; // DrawerTypes会自动包含profile的排他规则,无需修改其他代码
内容的提问来源于stack exchange,提问作者Inon shachar
相关产品推荐
相关产品推荐

