[英]How to handle props injected by HOC in React with Typescript?
我创建了一个简单的HOC,它在组件中注入方法translate
。
export interface IMessageProps {
translate: (key: string) => string;
}
export const message = <P extends object>(
Component: React.ComponentType<P & IMessageProps>
): React.SFC<P & IMessageProps> => (props: P) => {
const translate = (key: string): string => messages[key];
return <Component {...props} translate={translate}/>;
};
用法:
class MyComponent extends React.Component<IMessageProps, {}> {
render() {
return (
<>{this.props.translate('hello.world')}</>
);
}
}
export default message(MyComponent);
当我想调用我的组件<MyComponent/>
因为tsc抱怨属性translate
没有传递给MyComponent
并期望像<MyComponent translate={...}/>
。
Type '{}' is not assignable to type 'IntrinsicAttributes & IMessageProps & { children?: ReactNode; }'.
Type '{}' is not assignable to type 'IMessageProps'.
Property 'translate' is missing in type '{}'.
所以我的问题是: 如何绕过这个假错误? 我不想在IMessageProps
中使translate
可选项,因为tslint会抱怨Cannot invoke an object which is possibly 'undefined'
。
编辑
Typescript 3.2打破了下面的代码。 除了jsx标签之外,不允许使用泛型类型参数进行3.2扩展操作,并且在那里检查不是很严格。 这个问题改变了这个。 传播操作没有得到更严格的检查,这会破坏代码。 我们可以做的最简单的调整是在props
上使用类型断言:
export const message = <P extends IMessageProps>(
Component: React.ComponentType<P>
): React.SFC<Pick<P, Exclude<keyof P, keyof IMessageProps>>> => (props: Pick<P, Exclude<keyof P, keyof IMessageProps>>) => {
const translate = (key: string): string => messages[key];
return <Component {...props as P} translate={translate} />;
};
3.2之前
您可以使用Pick
从P
和Exclude
选择属性,从返回的SCF
排除IMessageProps
的属性,以排除IMessageProps
的键
export interface IMessageProps {
translate: (key: string) => string;
}
export const message = <P extends IMessageProps>(
Component: React.ComponentType<P>
): React.SFC<Pick<P, Exclude<keyof P, keyof IMessageProps>>> => (props: Pick<P, Exclude<keyof P, keyof IMessageProps>>) => {
const translate = (key: string): string => messages[key];
return <Component {...props} translate={translate} />;
};
class MyComponent extends React.Component<IMessageProps, {}> {
render() {
return (
<>{this.props.translate('hello.world')}</>
);
}
}
const MyComponentWrapped = message(MyComponent);
let d = <MyComponentWrapped /> // works
3.5及以上
您可以使用Omit<P, keyof IMessageProps>
而不是Pick<P, Exclude<keyof P, keyof IMessageProps>>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.