I set a state in my page component formData and I would like to create a context in my form component to use it in each form child component. Without TS everything works perfectly. But with TS, it tell me on setFormData, username and email does not exist on type IFormValues.
I would like to find a tips to say "hey Form component data type is ..." and stay generic in my Form component.
My page
const RegisterPage: NextPage = () => {
const [formData, setFormData] = useState({
username: '',
email: '',
})
return (
<Form state={[formData, setFormData]} name="mySuperForm">...</Form>
)
}
My component
interface IFormValues {
[key: string]: string | number
}
interface IFormProps extends FormHTMLAttributes<Element> {
state: [IFormValues, Dispatch<SetStateAction<IFormValues>>]
name: string
}
interface IFormContext {
values: IFormValues
setValues: Dispatch<SetStateAction<IFormValues>>
name: string
}
const FormContext = createContext<Partial<IFormContext>>({})
const Form: FC<IFormProps> = (props) => {
const cleanProps = {...props, state: undefined}
return (
<FormContext.Provider value={{
values: props.state[0],
setValues: props.state[1],
name: props.name
}}>
<form {...cleanProps} />
</FormContext.Provider>
)
}
If I use that:
interface IFormValues {
username: string
email: string
}
everything works