'How can I convert this JS function to TS?
I came across this JS function in react-hook-form docs:
import React from "react";
import { useForm } from "react-hook-form";
export default function Form({ defaultValues, children, onSubmit }) {
const methods = useForm({ defaultValues });
const { handleSubmit } = methods;
return (
<form onSubmit={handleSubmit(onSubmit)}>
{React.Children.map(children, child => {
return child.props.name
? React.createElement(child.type, {
...{
...child.props,
register: methods.register,
key: child.props.name
}
})
: child;
})}
</form>
);
}
I want to convert it to TS. I tried following:
import React, {ReactNode} from "react";
import { SubmitHandler, useForm } from "react-hook-form";
interface RhfFormProps {
defaultValues?: {};
onSubmit: SubmitHandler<{}>;
children?: ReactNode;
}
export default function Form({ defaultValues, children, onSubmit }: RhfFormProps) {
const methods = useForm({ defaultValues });
const { handleSubmit } = methods;
return (
<form onSubmit={handleSubmit(onSubmit)}>
{React.Children.map(children, (child) => {
return child.props.name
? React.createElement(child.type, {
...{
...child.props,
register: methods.register,
key: child.props.name,
},
})
: child;
})}
</form>
);
}
But it gives following errors:
For
childvariable:Object is possibly 'null' or 'undefined'.For
propsvariable:Property 'props' does not exist on type 'string | number | boolean | {} | ReactElement<any, string | JSXElementConstructor<any>> | ReactPortal'.
Property 'props' does not exist on type 'string'.
How do I do this?
Update
As suggested in answer by Noah, I tried to introduce generics:
interface RhfFormProps<T> {
defaultValues?: T;
onSubmit: SubmitHandler<T>;
children?: ReactNode;
}
export default function Form<T>({ defaultValues, children, onSubmit }: RhfFormProps<T>) {
const methods = useForm({ defaultValues });
const { handleSubmit } = methods;
return (
<form onSubmit={handleSubmit(onSubmit)}>
{React.Children.map(children, (child) => {
return child.props.name
? React.createElement(child.type, {
...{
...child.props,
register: methods.register,
key: child.props.name,
},
})
: child;
})}
</form>
);
}
However, I still get some errors:
On
defaultValues:Type 'T' is not assignable to type 'UnpackNestedValue<DeepPartial<T>>'.Original error on
child.propsis not eliminated:Property 'props' does not exist on type 'string | number | boolean | {} | ReactElement<any, string | JSXElementConstructor<any>> | ReactPortal'.Error on
child.type:Property 'type' does not exist on type 'string | number | boolean | {} | ReactElement<any, string | JSXElementConstructor<any>> | ReactPortal'.
Solution 1:[1]
- Do not use
{}as a Type - For child you have to do something like
if (!child) return <p>Error</p>, else return <your code/> - For props do not write out every parameter, try it like this:
interface RhfFormProps {
defaultValues?: {};
onSubmit: SubmitHandler<{}>;
children?: ReactNode;
}
export default function Form(props: RhfFormProps) {
...yourCode
}
- I think you should google for Typescript Generics
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Noah Buchmann |
