我有一个简单的通用反应组件,我将不总是知道我将使用哪种元素类型或道具,并且不想为每个电位设置一个接口道具
使用TS v2.9。
在这种情况下,我正在使用React Antial且不应不应相关的事实。
import React, { StatelessComponent as SC } from "react";
interface IGenComponentProps {
/**
* Component type
*/
ComponentName: string;
/**
* Test Id used for automation testing
*/
testId?: string;
/**
* I'd like to define this here to supress TS errors I'm getting
*/
remainderProps?: any;
}
const GenComponent:SC<IGenComponentProps> = ({ComponentName, testId, children, ...remainderProps}) => {
return (
<ComponentName id={testId} {...remainderProps}>
{children}
</ComponentName>
)
}
export default GenComponent;
这样可以正常工作,但是我在使用类似组件时会遇到TS错误:
<GenComponent
ComponentName={Image}
testId="test-image"
source={{uri: 'someImageSrc'}}
opacity={0.1}
/>
[ts]属性"源"在类型'intinsiCattributes&amp;IgencomponentProps&amp;{儿童?:ReactNode;}'。
[ts]属性'不透明度'不存在于'intinsiCattributes&amp;IgencomponentProps&amp;{儿童?:ReactNode;}'。
或:
<GenComponent
ComponentName={View}
testId="left-container"
accessibilityHint="left-container"
>
{ someContent }
</GenComponent>
[ts]属性'可访问性'不存在于类型'intrinsiCattributes&amp;IgencomponentProps&amp;{儿童?:ReactNode;}'。
如果您想能够允许任何名称的属性而不枚举这些名称,则可以做这样的事情:
interface IGenComponentProps {
ComponentName: string;
testId?: string;
[key: string]: any;
}
请注意,您对此进行了有限的检查。您的IDE基本上将强制执行该组件名称存在并且是一个字符串,并且如果存在testID,则是字符串。其他任何东西都是免费的,但至少可以。
您可以放松组件的道具接口,但是所有的gencomponents都会丢失所有孩子的类型信息。
相反,我将使用通用高阶组件:
interface ITest {
id: string;
}
function withId<T>(WrappedComponent) {
return class extends Component<ITest & T> {
public render() {
return <WrappedComponent id={this.props.id} {...this.props} />;
}
};
}
const TestableImage = withId<ImageProps>(Image);
const ExampleUsage = props =>
<View>
<TestableImage
id="required"
source={{ uri: "also required" }}
// Plus any other optional image image props
/>
</View>;
在这种情况下,您的包装组件将具有道具接口ITest & ImageProps
我找到了有关此模式的好文章。