#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.