我正在使用 Typescript,我想对通用组件进行道具验证。我想创建一个 Field 组件,它呈现标签、错误消息和作为道具传递的组件。我进行了多次尝试以使其工作,但其中一部分或另一部分都失败了。我还阅读了数十篇文章,但找不到任何人面临完全相同的问题。
这是我到目前为止所得到的:
interface IFieldProps<P> {
is: React.ComponentType<P>;
}
class Field<P> extends React.PureComponent<IFieldProps<P>> {
render() {
const { is, ...rest } = this.props;
const Component = is;
return (
<div>
<Component {...rest} />
</div>
);
}
}
interface ITextInputProps {
value: string
}
class TextInput extends React.PureComponent<ITextInputProps> {
render() {
return (
<input {...this.props} />
);
}
}
const render = () => <Field is={TextInput} />;
打字稿编译器并没有大喊value
该方法中缺少该道具render
,因此我将使其IFieldProps
扩展自P
它应该使其工作:
interface IFieldProps<P> extends P {
is: React.ComponentType<P>;
}
编译器现在说“一个接口只能扩展一个类或另一个接口”。好的,那我就把它变成一个类型,不用担心:
type IFieldProps<P> = P & {
is: React.ComponentType<P>;
}
现在一切都搞砸了。它大喊...rest
“Rest 类型只能从对象类型创建”。它大喊<Component />
“JSX 元素类型'组件'没有任何构造或调用签名”。最后,它在<Field />
那个value
道具丢失时大喊大叫——与此同时,道具上的自动完成功能在 vscode 中停止工作。我认为如果我对 P 有一些限制(例如P extends {}
)可以解决一些问题,但事实并非如此。
如何制作一个通用组件来继承作为道具传递的组件的道具?还是有些过于复杂?其他人如何解决这个问题?