I am trying to create a functional component in a react + typescript project that is using redux-form. I have created a generic form component and I want to pass a prop to it. Everything is working except the interface definition for the component props. I can use any and it works but then whats the point. I've tried a few different combinations from other posts I've found from a google search (commented out) but nothing is working.
The code:
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 & Stream): void;
}
// type StreamFormProps = CustomComponentProps & InjectedFormProps<{}, CustomComponentProps>;
// CustomComponentProps & 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 & CustomInputFieldProps): JSX.Element => {
const className = `field ${meta.error && meta.touched ? 'error' : ''}`;
return (
<div className={className}>
<label>{label}</label>
<input {...input} />
{renderError(meta)}
</div>
);
};
const renderError = ({ error, touched }: WrappedFieldMetaProps) => {
if (touched && 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);
The error I am getting:
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> & { children?: ReactNode; }' but required in type 'CustomComponentProps'.ts(2345)
StreamForm.tsx(17, 3): 'onSubmit' is declared here.