ソースを参照

fix(app.tsx): add safe check for readyPromise (#2489)

* fix(app.tsx): add safe check for readyPromise

* make type-safe

Co-authored-by: dwelle <luzar.david@gmail.com>
Aakansha Doshi 4 年 前
コミット
8f8fd023f8
4 ファイル変更15 行追加8 行削除
  1. 3 3
      src/components/App.tsx
  2. 3 1
      src/excalidraw-app/index.tsx
  3. 3 0
      src/global.d.ts
  4. 6 4
      src/types.ts

+ 3 - 3
src/components/App.tsx

@@ -301,9 +301,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
     };
     if (excalidrawRef) {
       const readyPromise =
-        typeof excalidrawRef === "function"
-          ? resolvablePromise<ExcalidrawImperativeAPI>()
-          : excalidrawRef.current!.readyPromise;
+        ("current" in excalidrawRef && excalidrawRef.current?.readyPromise) ||
+        resolvablePromise<ExcalidrawImperativeAPI>();
+
       const api: ExcalidrawImperativeAPI = {
         ready: true,
         readyPromise,

+ 3 - 1
src/excalidraw-app/index.tsx

@@ -24,7 +24,9 @@ import { ExcalidrawElement } from "../element/types";
 import { SAVE_TO_LOCAL_STORAGE_TIMEOUT } from "./app_constants";
 import { EVENT_LOAD, EVENT_SHARE, trackEvent } from "../analytics";
 
-const excalidrawRef: React.MutableRefObject<ExcalidrawAPIRefValue> = {
+const excalidrawRef: React.MutableRefObject<
+  MarkRequired<ExcalidrawAPIRefValue, "ready" | "readyPromise">
+> = {
   current: {
     readyPromise: resolvablePromise(),
     ready: false,

+ 3 - 0
src/global.d.ts

@@ -43,6 +43,9 @@ type ResolutionType<T extends (...args: any) => any> = T extends (
 // https://github.com/krzkaczor/ts-essentials
 type MarkOptional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
 
+type MarkRequired<T, RK extends keyof T> = Exclude<T, RK> &
+  Required<Pick<T, RK>>;
+
 // PNG encoding/decoding
 // -----------------------------------------------------------------------------
 type TEXtChunk = { name: "tEXt"; data: Uint8Array };

+ 6 - 4
src/types.ts

@@ -133,14 +133,16 @@ export declare class GestureEvent extends UIEvent {
 export type LibraryItem = readonly NonDeleted<ExcalidrawElement>[];
 export type LibraryItems = readonly LibraryItem[];
 
+// NOTE ready/readyPromise props are optional for host apps' sake (our own
+// implem guarantees existence)
 export type ExcalidrawAPIRefValue =
   | (ExcalidrawImperativeAPI & {
-      readyPromise: ResolvablePromise<ExcalidrawImperativeAPI>;
-      ready: true;
+      readyPromise?: ResolvablePromise<ExcalidrawImperativeAPI>;
+      ready?: true;
     })
   | {
-      readyPromise: ResolvablePromise<ExcalidrawImperativeAPI>;
-      ready: false;
+      readyPromise?: ResolvablePromise<ExcalidrawImperativeAPI>;
+      ready?: false;
     };
 
 export interface ExcalidrawProps {