react-filepond
react-filepond copied to clipboard
Typescript incompatibility with onupdatefiles and files props
Is there an existing issue for this?
- [X] I have searched the existing issues
Have you updated React FilePond, FilePond, and all plugins?
- [X] I have updated FilePond and its plugins
Describe the bug
I am a new adopter of this library, and I am using typescript. However, I cannot figure out how to have my files in state match the type demanded by onupdatefiles.
Reproduction
export default function FreePollForm() {
// State for the file input
const [files, setFiles] = useState<Array<FilePondInitialFile | File | Blob | string>>([]);
const [formData, setFormData] = useState({});
const filepondRef = useRef<FilePond>(null)
return (
<FormItem>
<FormLabel>Image</FormLabel>
<FormControl>
<FilePond
ref={filepondRef}
files={files}
onupdatefiles={setFiles}
allowMultiple={false}
name="files"
labelIdle='Drag & Drop your files or <span className="filepond--label-action">Browse</span>'
/>
</FormControl>
</FormItem>
)
Here I am getting an error with onupdatefiles:
No overload matches this call.
Overload 1 of 2, '(props: FilePondProps): FilePond', gave the following error.
Type 'Dispatch<SetStateAction<(string | Blob | FilePondInitialFile | File)[]>>' is not assignable to type '(files: FilePondFile[]) => void'.
Types of parameters 'value' and 'files' are incompatible.
Type 'FilePondFile[]' is not assignable to type 'SetStateAction<(string | Blob | FilePondInitialFile | File)[]>'.
Type 'FilePondFile[]' is not assignable to type '(string | Blob | FilePondInitialFile | File)[]'.
Type 'FilePondFile' is not assignable to type 'string | Blob | FilePondInitialFile | File'.
Property 'options' is missing in type 'FilePondFile' but required in type 'FilePondInitialFile'.
Overload 2 of 2, '(props: FilePondProps, context: any): FilePond', gave the following error.
Type 'Dispatch<SetStateAction<(string | Blob | FilePondInitialFile | File)[]>>' is not assignable to type '(files: FilePondFile[]) => void'.ts(2769)
And when I switch the setFiles type to
const [files, setFiles] = useState<Array<FilePondFile>>([]);
I get an error on the files prop:
No overload matches this call.
Overload 1 of 2, '(props: FilePondProps): FilePond', gave the following error.
Type 'FilePondFile[]' is not assignable to type '(string | Blob | FilePondInitialFile | ActualFileObject)[]'.
Type 'FilePondFile' is not assignable to type 'string | Blob | FilePondInitialFile | ActualFileObject'.
Property 'options' is missing in type 'FilePondFile' but required in type 'FilePondInitialFile'.
Overload 2 of 2, '(props: FilePondProps, context: any): FilePond', gave the following error.
Type 'FilePondFile[]' is not assignable to type '(string | Blob | FilePondInitialFile | ActualFileObject)[]'.ts(2769)
So I am not entirely sure what to do here since they are expecting two different types but they handle the same objects
Environment
- Device: MacOs M1
- OS: Sonoma 14.5
- Broser: Firefox 126.0
- React version: 18
As a workaround I am coercing typescript into thinking the types are correct. though this works for now, idk if there are going to be unforeseen problems later with this:
<FilePond
ref={filepondRef}
files={files}
onupdatefiles={(fileItems: FilePondFile[]) => {
setFiles(
fileItems.map(
(fileItem) => fileItem.file as File,
),
)
}}
allowMultiple={false}
/>
@anthonysgro Hey, I'm unfortunately not proficient enough in TypeScript to solve this based on the descriptions above. I guess coercing will work for now and I don't see that causing any issues.
I ran into this also and it took me awhile to figure out how to get the sample above working since the FilePondFile wasn't exportable by react-filepond. Finally got it working with
import { FilePondFile, FilePondInitialFile } from 'filepond'
Thanks @anthonysgro for the fix!
@rikschennink Maybe a sample/help on the docs could be a fix in the meantime. I just copied the example from the site for react but hit type errors and this ticket helped me solve it! So like even just a If using react, you'll need to do this... sort of thing.
@OscarGodson Thanks for the suggestion, I've updated the docs with a short annotation.
This is what I did in my case.
import { FilePondFile } from 'filepond';
...
const [files, setFiles] = useState<File[]>([]);
...
<FilePond
files={files}
onupdatefiles={(fileItems: FilePondFile[]) => {
setFiles(fileItems.map((f: FilePondFile) => f.file as File));
}}
allowMultiple={true}
maxFiles={3}
server="/api"
name="files"
labelIdle='Drag & Drop your files or <span class="filepond--label-action">Browse</span>'
/>
...
Thanks @arantebw, it looks like this is the clean way to solve the issue.
The core filepond code states that they plan to transition from ActualFileObject to the native File type, at which point the undesired as File cast will no longer be necessary.
// TODO replace all references to `ActualFileObject` with native `File`
/**
* @deprecated Don't use this type explicitly within your code. It'll be replaced with the native `File` type in a future release.
*/
export type ActualFileObject = Blob & { readonly lastModified: number; readonly name: string };
https://github.com/pqina/filepond/blob/afebde20f4d0cffa09ff18dbf8d79c2c1d5a1d80/types/index.d.ts#L35-L39