Home > Mobile >  How to use TypeScript generics to extend a library function with React's useCallback
How to use TypeScript generics to extend a library function with React's useCallback

Time:10-12

I am creating a component with react-dropzone. react-dropzone provides a useDropzone() which takes a object for arguments, e.g. useDropzone({ onDrop }).

CodeSandbox example is here

useDropzone's type is:

export function useDropzone(options?: DropzoneOptions): DropzoneState;

DropzoneOptions are

export type DropzoneOptions = Pick<React.HTMLProps<HTMLElement>, PropTypes> & {
  onDrop?: <T extends File>(acceptedFiles: T[], fileRejections: FileRejection[], event: DropEvent) => void;
};

How do I type acceptedFiles (instead of any) by typing the generic T in a useCallback?

  const onDrop = useCallback((acceptedFiles: any) => {
    acceptedFiles.forEach((file) => {
      console.log(file)
    })
  }, [])

CodePudding user response:

You can add type to function inside the useCallback

const onDrop = useCallback(<T extends File>(acceptedFiles: T[]) => {
  acceptedFiles.forEach((file) => {
    console.log(file)
  })
}, [])

You also have the option to directly use the type on useCallback

type OnDropType = NonNullable<DropzoneOptions['onDrop']>;

const onDrop = useCallback<OnDropType>((acceptedFiles) => {
  acceptedFiles.forEach((file) => {
    console.log(file)
  })
}, [])

NonNullable is needed because useCallback doesn't like undefined as function type.

  • Related