Универсальный компонент машинописного текста наследует компоненты реквизита - PullRequest
0 голосов
/ 22 декабря 2018

Я использую 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} />;

Компилятор машинописного текстане кричит о том, что в методе render отсутствует пропеллер *1007*, поэтому я заставлю IFieldProps расширяться от P, и это должно заставить его работать:

interface IFieldProps<P> extends P {
    is: React.ComponentType<P>;
}

теперь компилятор говорит, что «интерфейс может расширять только класс или другой интерфейс».Хорошо, тогда я сделаю это типом, не беспокойтесь:

type IFieldProps<P> = P & {
    is: React.ComponentType<P>;
}

Теперь все облажалось.На ...rest выкрикивается, что «остальные типы могут быть созданы только из типов объектов».На <Component /> выкрикивается, что «тип элемента JSX« Компонент »не имеет никакой конструкции или сигнатуры вызова».И, наконец, <Field /> выкрикивает, что value prop отсутствует - и в то же время автозаполнение на props перестает работать в vscode.Я думал, что если бы у меня были некоторые ограничения на P (например, P extends {}), которые бы исправили некоторые проблемы, но этого не произошло.

Как я могу сделать общий компонент, который наследует реквизитыКомпонент прошел как опору?Все еще что-то слишком сложно?Как другие люди решают эту проблему?

1 Ответ

0 голосов
/ 22 декабря 2018

Это работает, когда реквизиты обернутых компонентов хранятся в другой пропе (вместо того, чтобы смешиваться с 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" |Исключить> нельзя назначить типу IntrinsicAttributes & LibraryManagedAttributes ["is"], P & {children ?: ReactNode;}>».Введите 'Pick & Readonly>, "children" |Exclude> 'нельзя назначить типу' LibraryManagedAttributes ["is"], P & {children ?: ReactNode;}> '.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...