Как использовать компонент redux-формы с текстом и пользовательскими реквизитами

#reactjs #typescript #redux-form

Вопрос:

Я пытаюсь создать функциональный компонент в проекте react typescript, который использует redux-форму. Я создал универсальный компонент формы и хочу передать ему реквизит. Все работает, кроме определения интерфейса для реквизитов компонентов. Я могу использовать любой, и это работает, но тогда в чем смысл. Я попробовал несколько различных комбинаций из других сообщений, которые я нашел в поиске Google (прокомментировал), но ничего не работает.

Код:

 import React from 'react';
import {
  Field,
  reduxForm,
  InjectedFormProps,
  WrappedFieldProps,
  WrappedFieldMetaProps,
} from 'redux-form';
import { Stream } from '../../constants';


interface CustomInputFieldProps {
  label?: string;
}

interface CustomComponentProps extends InjectedFormProps {
  onSubmit(values: any amp; Stream): void;
}

// type StreamFormProps = CustomComponentProps amp; InjectedFormProps<{}, CustomComponentProps>;
// CustomComponentProps amp; InjectedFormProps<{}, CustomComponentProps>

// what to replace any with?
const StreamForm = ({ handleSubmit, onSubmit }: any) => {

  // values is actually typed as any o_0
  // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/9ce52af612e29ff0bac4317bde78d0acab29afdb/types/redux-form/v6/lib/Form.d.ts#L5
  const onFormSubmit = (values: any): void => {
    const { title, description } = values;
    onSubmit({ title, description });
  };


  const renderInput = ({ input, label, meta }: WrappedFieldProps amp; CustomInputFieldProps): JSX.Element => {
    const className = `field ${meta.error amp;amp; meta.touched ? 'error' : ''}`;
    return (
      <div className={className}>
        <label>{label}</label>
        <input {...input} />
        {renderError(meta)}
      </div>
    );
  };

  const renderError = ({ error, touched }: WrappedFieldMetaProps) => {
    if (touched amp;amp; error) {
      return (
        <div className="ui error message">
          <div className="header">{error}</div>
        </div>
      );
    }
  };

  return (
    <form onSubmit={handleSubmit(onFormSubmit)} className="ui form error">
      <Field
        name="title"
        component={renderInput}
        label="Enter Title"
      />
      <Field
        name="description"
        component={renderInput}
        label="Enter Description"
      />
      <button className="ui button primary">Submit</button>
    </form>
  );
};

const validate = (formValues: any): { title?: string; description?: string; } => {
  const errors: { title?: string; description?: string; } = {};

  if (!formValues.title) {
    errors.title = 'You must enter a title';
  }

  if (!formValues.description) {
    errors.description = 'You must enter a description';
  }

  return errors;
};

export default reduxForm({ form: 'streamForm', validate })(StreamForm);
 

Ошибка, которую я получаю:

 Argument of type '({ handleSubmit, onSubmit }: StreamFormProps) => JSX.Element' is not assignable to parameter of type 'ComponentType<InjectedFormProps<any, {}, string>>'.
  Type '({ handleSubmit, onSubmit }: StreamFormProps) => JSX.Element' is not assignable to type 'FunctionComponent<InjectedFormProps<any, {}, string>>'.
    Types of parameters '__0' and 'props' are incompatible.
      Type 'PropsWithChildren<InjectedFormProps<any, {}, string>>' is not assignable to type 'StreamFormProps'.
        Property 'onSubmit' is missing in type 'InjectedFormProps<any, {}, string> amp; { children?: ReactNode; }' but required in type 'CustomComponentProps'.ts(2345)
StreamForm.tsx(17, 3): 'onSubmit' is declared here.