1

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.

1
  • 2
    Why did you copy the definition of valuesInterface in different files? Also useForm is not a generic function, remove the <valuesInterface> part. Commented Sep 21, 2021 at 2:47

1 Answer 1

1

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 });
        }, [])
    ]
};
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.