Reputation: 849
I'm new to TypeScript and trying to create a custom hook called useForm
using useState()
.
Following is the code for useForm
:
import {useState} from 'react';
interface valuesInterface {
email: string
password: string
}
export const useForm = (initialValue: valuesInterface) => {
const [values, setValues] = useState<valuesInterface>(initialValue);
return [
values,
(e: { target: { name: any; value: any; }; }) => {
setValues({
...values,
[e.target.name]: e.target.value
})
}
]
};
I import that function into my main App
:
import {useForm} from './utils/useForm';
import './App.css';
interface valuesInterface {
email: string,
password: string
}
const App = () => {
const [values, handleChange] = useForm<valuesInterface>({email: '', password: ''});
return (
<div className="App">
<input name='email' value={values.email} onChange={handleChange}/>
<input type='password' name='password' value={values.password} onChange={handleChange} />
</div>
);
}
export default App;
As you can see, I've defined the interface valuesInterface
to describe the data shape as an object. I'm not if I've done it properly, though. However, my error seems to have something to do with the parameters.
Error:
Failed to compile.
/frontend/src/App.tsx
TypeScript error in
/frontend/src/App.tsx(10,42):
Expected 0 type arguments, but got 1. TS2558
8 |
9 | const App = () => {
> 10 | const [values, handleChange] = useForm<valuesInterface>({email: '', password: ''});
| ^
11 |
12 | return (
13 | <div className="App">
Have I defined the type correctly, and am I utilising it as it should be in my custom hook?
Thanks! Any help would be much appreciated.
Upvotes: 0
Views: 4194
Reputation: 26
The useForm
hook isn't a generic function.
Workaround:
// file: useForm
import { useState, useCallback } from 'react';
export const useForm = <T extends Record<string, unknown>(initialState: T) => {
const [values, setValues] = useState<T>(initialState);
return [
values,
useCallback((event: { target: { name: string; value: unknown; }; }) => {
setValues(v => ({ ...v, [event.target.name]: event.target.value });
}, [])
]
};
Upvotes: 1