上下文消费者的 HoC 导致子组件出现类型错误
HoC for context consumer causing type error with child component
我遇到了一个问题,我尝试编写一个 HoC 来包装组件,这些组件应该可以通过新注入的道具访问特定的上下文。
有一个 Gist 与基本上包含以下片段的教程相关:
export function withAppContext<
P extends { appContext?: AppContextInterface },
R = Omit<P, 'appContext'>
>(
Component: React.ComponentClass<P> | React.StatelessComponent<P>
): React.SFC<R> {
return function BoundComponent(props: R) {
return (
<AppContextConsumer>
{value => <Component {...props} appContext={value} />}
</AppContextConsumer>
);
};
}
同样有,如下所示:
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>
)
}
}
它们几乎相同,而且显然曾经工作过一次,但现在已不再如此。使用这两种变体时,consume 的 render prop 中的子组件 Component
带有下划线,并显示以下错误消息:
Type '{ exploreContext: IExploreContextStore; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Property 'exploreContext' does not exist on type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
我发生问题的示例代码如下:
type WithExploreContext = { exploreContext?: IExploreContextStore };
export function withExploreContext<P extends WithExploreContext>(ChildComponent: ComponentType<P>) {
return function WrappedComponent(
props: Pick<P, Exclude<keyof P, keyof WithExploreContext>>
) {
return <Consumer>{(value) => <ChildComponent {...props} exploreContext={value} />}</Consumer>;
};
}
我几乎不知道这些片段有什么问题,也不知道为什么它们不再按预期工作。
仅将 props
传播到子组件是不够的。它在使用 {...props as P}
.
将其转换为 P
后立即开始工作
从 3.2 开始 behaviour of the spread operator for generics has changed。显然 props
的类型作为负面影响被删除,但您可以通过在传播回包装组件时使用 {...props as P}
将其转换回 P
来解决这个问题。
我遇到了一个问题,我尝试编写一个 HoC 来包装组件,这些组件应该可以通过新注入的道具访问特定的上下文。
有一个 Gist 与基本上包含以下片段的教程相关:
export function withAppContext<
P extends { appContext?: AppContextInterface },
R = Omit<P, 'appContext'>
>(
Component: React.ComponentClass<P> | React.StatelessComponent<P>
): React.SFC<R> {
return function BoundComponent(props: R) {
return (
<AppContextConsumer>
{value => <Component {...props} appContext={value} />}
</AppContextConsumer>
);
};
}
同样有
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>
)
}
}
它们几乎相同,而且显然曾经工作过一次,但现在已不再如此。使用这两种变体时,consume 的 render prop 中的子组件 Component
带有下划线,并显示以下错误消息:
Type '{ exploreContext: IExploreContextStore; }' is not assignable to type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
Property 'exploreContext' does not exist on type 'IntrinsicAttributes & P & { children?: ReactNode; }'.
我发生问题的示例代码如下:
type WithExploreContext = { exploreContext?: IExploreContextStore };
export function withExploreContext<P extends WithExploreContext>(ChildComponent: ComponentType<P>) {
return function WrappedComponent(
props: Pick<P, Exclude<keyof P, keyof WithExploreContext>>
) {
return <Consumer>{(value) => <ChildComponent {...props} exploreContext={value} />}</Consumer>;
};
}
我几乎不知道这些片段有什么问题,也不知道为什么它们不再按预期工作。
仅将 props
传播到子组件是不够的。它在使用 {...props as P}
.
P
后立即开始工作
从 3.2 开始 behaviour of the spread operator for generics has changed。显然 props
的类型作为负面影响被删除,但您可以通过在传播回包装组件时使用 {...props as P}
将其转换回 P
来解决这个问题。