我正在使用Typescript,我想对通用组件进行prop验证。我想创建一个Field组件,该组件呈现标签,错误消息和作为prop传递的组件。我进行了多次尝试,以使其正常运行,但是其中一部分或另一部分均无法通过。我也阅读了数十篇文章,但找不到任何人遇到完全相同的问题。
这是到目前为止我得到的:
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
上大喊“其他类型只能从对象类型创建”。在<Component />
上大喊“ JSX元素类型'Component'没有任何构造或调用签名”。最后,在<Field />
上大喊value
道具缺失-同时,道具的自动完成功能在vscode中停止工作。
我认为,如果我对P施加一些约束(例如P extends {}
)可以解决一些问题,但事实并非如此。
如何制作通用组件,以继承作为道具传递的组件的道具?还是有些复杂?其他人如何解决这个问题?
答案 0 :(得分:0)
当包装的组件道具保留在另一个道具中(而不是与is
混合使用)时,它起作用:
interface IFieldProps<P> {
is: React.ComponentType<P>;
props: P;
};
class Field<P> extends React.PureComponent<IFieldProps<P>> {
render() {
const { is, props } = this.props;
const Component = is;
return (
<div>
<Component {...props} />
</div>
);
}
}
interface ITextInputProps {
readonly value: string;
}
class TextInput extends React.PureComponent<ITextInputProps> {
render() {
return (
<input {...this.props} />
);
}
}
const render = () => <Field is={TextInput} props={{ value: ''} } />;
我无法根据以下消息找到错误的来源:
输入“选择并 只读>,“子级” |排除>'不是 可分配给类型'IntrinsicAttributes& LibraryManagedAttributes [“ is”],P和{子代?: ReactNode; }>'。输入“ Pick& 只读>,“子级” |排除>'不是 可分配给类型'LibraryManagedAttributes [“ is”],P和 {子代?:ReactNode; }>'。