Search code examples
typescriptnext.jspromiseprisma

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


/component/button.tsx

"client component"

export const DeleteButton = ({ id }: { id: string }) => {
  const deleteImageWithId = deleteImage.bind(null, id);
  return (
    <form
      action={deleteImageWithId}
      className="py-3 text-sm bg-gray-50 rounded-br-md w-full hover:bg-gray-100 text-center"
    >
      <DeleteBtn />
    </form>
  );
};



/lib/actions.ts

"server component"

// Delete Image
export const deleteImage = async (id: string) => {
  const data = await getImageById(id);
  if (!data) return { message: "No data found" };

  await del(data.image);
  try {
    await prisma.upload.delete({
      where: { id },
    });
  } catch (error) {
    return { message: "Failed to delete data" };
  }

  revalidatePath("/");
};

Error

enter image description here

Error message:

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

Solution

  • () => Promise<{ message: string; } | undefined> is the type of deleteImageWithId, aka deleteImage.bind(null,id). You take no arguments () and return a promise of either an object containing a field message which is a string, or something undefined.

    You are trying to put that object somewhere that expects an object of type string | ((formData: FormData) => void | Promise) | undefined.

    This is probably action; as the action of a form, it is passed the form data. Your form is pretty empty.

    Probably the easiest way to deal with this would be to create a lambda wrapper that takes a FormData and throws it away.

    const deleteImageWithId = async (discard: FormData)=>{
      /* await maybe? */ deleteImage(id);
    };
    

    Something like that should fix up the type of deleteImageWithId so it matches one of the expected signatures of action.

    Failing the above working, you may have to modify deleteImage to not return { message: "whatever" } that isn't being consumed by the code using it, or write a wrapper that uses that to do something.