react-widget icon indicating copy to clipboard operation
react-widget copied to clipboard

Typescript type updates

Open johnnaegle opened this issue 3 years ago • 3 comments

Hello, this patch, which I am applying locally with patch-package fixes a number of issues with the type definitions in this project. I do not claim this is 100% correct, I made most of these fixes by debugging and reverse engineering the types.

A couple notable ones:

  • FileInfo: the uuid/mimeType can both be null for new files when the validator is invoked
  • The dialog API fileColl typing is wrong. In general with the existing type defs it looks like there is confusing between what is a FileInfo and what is a FileUpload.
  • The FileGroup type was missing.
  • Without the types being exported, its hard to write typed functions, so some types got exported

Here is the diff that solved my problem:

diff --git a/node_modules/@uploadcare/react-widget/types/index.d.ts b/node_modules/@uploadcare/react-widget/types/index.d.ts
index 7622a02..8965b49 100644
--- a/node_modules/@uploadcare/react-widget/types/index.d.ts
+++ b/node_modules/@uploadcare/react-widget/types/index.d.ts
@@ -231,13 +231,13 @@ interface SourceInfo {
 }
 
 interface FileInfo {
-  uuid: Uuid;
+  uuid: null | Uuid;
   name: null | string;
   size: null | number;
   isStored: null | boolean;
   isImage: null | boolean;
   originalImageInfo: null | OriginalImageInfo;
-  mimeType: string;
+  mimeType: null | string;
   originalUrl: null | string;
   cdnUrl: null | string;
   cdnUrlModifiers: null | string;
@@ -252,10 +252,40 @@ interface FileInfo {
 
 type OnTabVisibilityCallback = (tab: string, shown: boolean) => void;
 
+interface Collection<T> {
+  onAdd: JQuery.Callbacks;
+  onRemove: JQuery.Callbacks;
+  onSort: JQuery.Callbacks;
+  onReplace: JQuery.Callbacks;
+  __items: T[];
+
+  add: (item: T) => JQuery.Callbacks | undefined;
+  remove: (item: T) => JQuery.Callbacks | undefined;
+  clear: () => JQuery.Callbacks[];
+  replace: (oldItem: T, newItem: T) => JQuery.Callbacks | undefined;
+  sort: (comparator: (a: T, b: T) => boolean) => JQuery.Callbacks;
+  get: (index: number) => T;
+  length: () => number;
+}
+
+interface UniqCollection<T> extends Collection<T> {
+  add: (item: T) => JQuery.Callbacks | undefined;
+}
+interface CollectionOfPromises<T> extends UniqCollection<JQuery.Deferred<T>> {
+  anyDoneList: JQuery.Callbacks;
+  anyFailList: JQuery.Callbacks;
+  anyProgressList: JQuery.Callbacks;
+
+  onAnyDone: unknown;
+  onAnyFail: unknown;
+  onAnyProgress: unknown;
+  lastProgresses: unknown;
+  autoThen: unknown;
+}
 interface DialogApi {
   addFiles(files: FileInfo[]): void;
   switchTab(tab: string): void;
-  fileColl: FileInfo[];
+  fileColl: CollectionOfPromises<FileInfo>;
   hideTab(tab: string): void;
   showTab(tab: string): void;
   isTabVisible(tab: string): boolean;
@@ -322,9 +352,29 @@ interface WidgetAPI {
   getInput: () => HTMLInputElement;
 }
 
-type FileUpload = JQuery.Deferred<FileInfo>;
+interface FileUpload extends JQuery.Deferred<FileInfo> {
+  cancel: () => FileUpload;
+}
+
+/**
+ * The result of uploading multiple files to upload care is a file group.
+ *
+ * The react upload care widget does not (yet) define this type.
+ *
+ * This type is reverse engineered from stepping into the debugger.
+ */
+ interface FileGroup {
+  cdnUrl: string;
+  count: number;
+  isImage: boolean;
+  isStored: boolean;
+  name: string;
+  size: number;
+  uuid: string;
+}
+
 interface FilesUpload {
-  promise: () => FileUpload;
+  promise: () => FileGroup;
   files: () => FileUpload[];
 }
 
@@ -365,6 +415,9 @@ export {
   Uuid,
   SourceInfo,
   FileInfo,
+  FileGroup,
+  FileUpload,
+  FilesUpload,
   DialogApi,
   OnTabVisibilityCallback,
   Settings,

This issue body was partially generated by patch-package.

johnnaegle avatar Mar 25 '21 17:03 johnnaegle

Fixed by #255

johnnaegle avatar Mar 29 '21 17:03 johnnaegle

EDIT: Reverting to v1.3.5 solves the problem

I'm still getting Property 'done' does not exist on type 'FileUpload | FilesUpload'. on v1.3.7 when running a very simple callback using onFileSelect, similar to the example on the docs.

It first complains about e possibly being null, and then once I correct for that, it complains about

Property 'done' does not exist on type 'FileUpload | FilesUpload'.
  Property 'done' does not exist on type 'FileUpload'.  TS2339
                        <Widget
                          ref={widgetApi}
                          clearable
                          onFileSelect={(e) => {
                            if (e !== null) {
                              e.done((file: any) => {
                                setFormContext((prevState: FormC) => ({
                                  ...prevState,
                                  uploadcareImage: file,
                                }));
                              });
                            }

thongly avatar Apr 12 '21 05:04 thongly

Here's my basic code snippet, in case anyone have a problem

const Home: NextPage = () => {


  function uploadFile(e: any){
    e.done(function(fileInfo: FileUpload | FilesUpload | undefined) {
      console.log(fileInfo);
    })
  }


  return (
    <div>
      Upload Your Document

      <Widget publicKey="YOUR_PUBLIC_KEY" 
              onFileSelect={(e) => uploadFile(e)}/>;
    </div>
  )
}

hilmanski avatar Sep 27 '22 02:09 hilmanski