如何为React组件Props指定条件类型?以Typography组件为例
问题:为Typography组件定义关联的color与shade类型
假设有如下定义Typography组件颜色与色调的theme对象:
const theme = { primary: [10, 20, 50, 100], secondary: [20, 30, 80], accent: [10, 20] }
Typography组件需要接收color、shade两个Props,其中color的类型已定义为keyof typeof theme。现在需要指定shade的类型,使其仅能接受对应color所选主题数组中的值——比如当color为accent时,shade只能是10或20,不能是30。
现有代码片段如下:
function Typography({ color, shade, children, }: { color: keyof typeof theme; shade: ???; children: React.ReactNode; }) { return <div>{children}</div>; } function Main() { return ( <Typography color="primary" shade={}> Some text </Typography> ); }
解决方案
要实现这种关联的类型约束,需要利用TypeScript的联合类型+映射类型,让color和shade的类型绑定在一起,具体实现如下:
1. 定义关联的Props类型
先创建一个映射类型,遍历theme的每个键,生成对应color和shade的组合,最终合并为联合类型:
type TypographyProps = { [K in keyof typeof theme]: { color: K; shade: (typeof theme)[K][number]; children: React.ReactNode; }; }[keyof typeof theme];
(typeof theme)[K][number]用于提取theme[K]数组中的所有元素类型,作为对应color下shade的有效值。- 最后通过
[keyof typeof theme]将映射出的所有对象类型合并为联合类型,确保color和shade的取值一一对应。
2. 重构Typography组件
将组件的参数类型替换为上面定义的TypographyProps:
function Typography({ color, shade, children, }: TypographyProps) { return <div>{children}</div>; }
3. 可选shade的扩展(可选)
如果需要让shade支持可选(比如设置默认色调),可以给shade添加可选标记?:
type TypographyProps = { [K in keyof typeof theme]: { color: K; shade?: (typeof theme)[K][number]; children: React.ReactNode; }; }[keyof typeof theme];
效果验证
完成后TypeScript会自动进行校验:
- 当
color="accent"时,shade只能传入10或20; - 当
color="primary"时,shade可以是10、20、50、100; - 传入不匹配的取值会直接触发类型错误。
内容的提问来源于stack exchange,提问作者aBhijit
相关产品推荐
相关产品推荐

