2

我正在使用 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 {})可以解决一些问题,但事实并非如此。

如何制作一个通用组件来继承作为道具传递的组件的道具?还是有些过于复杂?其他人如何解决这个问题?

4

1 回答 1

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: ''} } />;

我无法根据消息找到错误的来源:

键入'Pick & Readonly>, "children" | Exclude>' 不可分配给类型 'IntrinsicAttributes & LibraryManagedAttributes["is"], P & { children?: ReactNode; }>'。键入'Pick & Readonly>, "children" | Exclude>' 不可分配给类型 'LibraryManagedAttributes["is"], P & { children?: ReactNode; }>'。

于 2018-12-22T19:12:15.333 回答