formsnext.jstypeerrorbind

Nextjs 15, Type error when calling a server action from a form with a bind


Using nextjs15, when I call a server action from a form in a server component with a bind, I have the following error when I compile my project for production mode (in dev mode, it works):

Type error: Type '() => Promise<{ message: string; }>' is not assignable to type 'string | ((formData: FormData) => void | Promise<void>) | undefined'.
  Type '() => Promise<{ message: string; }>' is not assignable to type '(formData: FormData) => void | Promise<void>'.
    Type 'Promise<{ message: string; }>' is not assignable to type 'void | Promise<void>'.
      Type 'Promise<{ message: string; }>' is not assignable to type 'Promise<void>'.
        Type '{ message: string; }' is not assignable to type 'void'.

  31 |
  32 |   return (
> 33 |     <form action={deleteInvoiceWithId}>
     |           ^
  34 |       <button type="submit" className="rounded-md border p-2 hover:bg-gray-100">
  35 |         <span className="sr-only">Delete</span>
  36 |         <TrashIcon className="w-4" />
Static worker exited with code: 1 and signal: null
 ELIFECYCLE  Command failed with exit code 1.

The code :

export function DeleteInvoice({ id }: { id: string }) {
  const deleteInvoiceWithId = deleteInvoice.bind(null, id);
  return (
    <form action={deleteInvoiceWithId}>
      <button type="submit" className="rounded-md border p-2 hover:bg-gray-100">
        <span className="sr-only">Delete</span>
        <TrashIcon className="w-4" />
      </button>
    </form>
  );
}

export async function deleteInvoice(id: string) {
    try {
      await sql`DELETE FROM invoices WHERE id = ${id}`;
      revalidatePath('/dashboard/invoices');
      return { message: 'Deleted Invoice.' };
    } catch (error) {
      return { message: 'Database Error: Failed to Delete Invoice.' };
    }
  }

Please note that this example comes from nextjs.org training course here


Solution

  • based on the error, the server action is returning something-- object of

    Type '{ message: string; }'
    

    though, next.js 15 form actions must return void or Promise as this is a server side execution rather. hence the rest of the error:

    is not assignable to type '(formData: FormData) => void | Promise<void>'
    

    remove return statement:

    export async function deleteInvoice(id: string) {
      try {
        await sql`DELETE FROM invoices WHERE id = ${id}`;
        revalidatePath('/dashboard/invoices');
      } catch (error) {
        console.error('Failed to delete invoice:', error);
        throw new Error('Failed to delete invoice');
      }
    }