Search code examples
javascriptreactjstypescriptnext.js

TypeScript "No overload matches this call"


I have an async function that makes a call to the backend and I want to it to return axios error message. Then I can list the messages in the form.

export async function register(
  prevState: string | undefined,
  formData: FormData
) {
  try {
    const res = await axios({
      method: "post",
      url: process.env.NEXT_PUBLIC_BACKEND_URL + "auth/register/",
      data: {
        username: formData.get("username"),
        email: formData.get("email"),
        password1: formData.get("password1"),
        password2: formData.get("password2"),
      },
    });
    if (res && res.status != 200 && res.status != 201) {
      return "Something went wrong";
    } else {
      return "ok";
    }
  } catch (error: any) {
    console.error(error);
    return Object.keys(error.response.data).map(
      (key) => error.response.data[key][0]
    );
  }
}
export default function RegisterPage() {
  const [errorMessage, dispatch] = useFormState(register, undefined);
  const { pending } = useFormStatus();

  if (errorMessage === "ok") {
    window.location.href = "/email/confirm/";
  }

  return (

  ...

        {errorMessage &&
          typeof errorMessage === "object" &&
          errorMessage.map((e, index) => (
            <div key={index}>
              <span>{e}</span>
            </div>
          ))}
  ...

  );
}

Typescript gives me an error for register in const [errorMessage, dispatch] = useFormState(register, undefined);:

No overload matches this call.
  Overload 1 of 2, '(action: (state: {} | undefined) => {} | Promise<{} | undefined> | undefined, initialState: {} | undefined, permalink?: string | undefined): [state: {} | undefined, dispatch: () => void, isPending: boolean]', gave the following error.
    Argument of type '(prevState: string | undefined, formData: FormData) => Promise<{}>' is not assignable to parameter of type '(state: {} | undefined) => {} | Promise<{} | undefined> | undefined'.
      Target signature provides too few arguments. Expected 2 or more, but got 1.
  Overload 2 of 2, '(action: (state: {} | undefined, payload: FormData) => {} | Promise<{} | undefined> | undefined, initialState: {} | undefined, permalink?: string | undefined): [state: ...]', gave the following error.
    Argument of type '(prevState: string | undefined, formData: FormData) => Promise<{}>' is not assignable to parameter of type '(state: {} | undefined, payload: FormData) => {} | Promise<{} | undefined> | undefined'.
      Types of parameters 'prevState' and 'state' are incompatible.
        Type '{} | undefined' is not assignable to type 'string | undefined'.
          Type '{}' is not assignable to type 'string'.

What is a correct way to return an object from an async function call? Or do I just need to define it properly?


Solution

  • Where is the useFormState coming from? And are you sure that it accepts a function with this call signature like:

    (
      prevState: string | undefined,
      formData: FormData
    ) => void
    
    

    not

    (
      prevState: {} | undefined,
      formData: FormData
    ) => void
    
    

    because in the error it states that it needs to be {} | undefined not string | undefined