Rahul
Rahul

Reputation: 849

How to resolve "Expected 0 type arguments, but got 1" error on TypeScript React Hook useState()?

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

Answers (1)

Mostafa Shamsitabar
Mostafa Shamsitabar

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

Related Questions