您大部分情况都是正确的,但缺少一些内容:
对于
Component
,请使用React.ComponentType<Props>
,它正确接受类组件和功能组件。我认为new () => ...
单独使用在这里不起作用,因为签名不能完全匹配。要
ThemedButton
在使用道具时将其排除在外,您必须使用一些看起来很神奇的语法:function ThemedComponent(props: Pick
>)
这是这样做的:
Exclude<keyof P, keyof ThemeAwareProps>
表示“获取的密钥P
,然后拿走其中的密钥ThemeAwareProps
”Pick<P, ...>
然后说:“从P
,仅返回具有这些属性的对象类型”
将这些结合起来,便得到了一个组件,它接受所有可以做的道具
ThemedButton,减去
theme道具,这样我们就可以做到
<ThemedButton/>没有错误。
这是完整的HOC:
function withTheme<P extends ThemeAwareProps>(Component: React.ComponentType<P>) { return function ThemedComponent(props: Pick<P, Exclude<keyof P, keyof ThemeAwareProps>>) { return ( <ThemeContext.Consumer> {(theme) => <Component {...props} theme={theme} />} </ThemeContext.Consumer> ) }}最后,关于该主题的一篇不错的博客文章,我从中收集了大部分此类信息。如果您愿意,它还包括一种缩短类型的
Pick<...>内容的方法
Omit。
编辑:休息/传播的行为已在3.2中更改,并且此错误作为不幸的副作用出现,导致
props与其他道具合并时被擦除的类型。当前可行的解决方法是强制转换
props为
P:
return ( <ThemeContext.Consumer> {(theme) => <Component {...props as P} theme={theme} />} </ThemeContext.Consumer> )


