From 2d325981ff86604804a6689e2f63128c4719057b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com>
Date: Wed, 9 Nov 2022 01:40:50 +0000
Subject: [PATCH] refactor: better typescript coercion

---
 examples/web/index.ts                         | 24 +++++++++----------
 .../web/react/components/button/button.tsx    |  7 +++---
 .../components/keyboard-gb/keyboard-gb.tsx    | 16 ++++++-------
 examples/web/react/components/link/link.tsx   |  2 +-
 .../web/react/components/overlay/overlay.tsx  | 18 +++++++-------
 .../components/panel-split/panel-split.tsx    |  2 +-
 .../react/components/paragraph/paragraph.tsx  |  2 +-
 7 files changed, 35 insertions(+), 36 deletions(-)

diff --git a/examples/web/index.ts b/examples/web/index.ts
index 5daac83a..036d5c0d 100644
--- a/examples/web/index.ts
+++ b/examples/web/index.ts
@@ -115,7 +115,7 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
 
         // boots the emulator subsystem with the initial
         // ROM retrieved from a remote data source
-        await this.boot({ loadRom: true, romPath: romUrl || undefined });
+        await this.boot({ loadRom: true, romPath: romUrl ?? undefined });
 
         // the counter that controls the overflowing cycles
         // from tick to tick operation
@@ -227,16 +227,16 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
 
             // runs the Game Boy clock, this operations should
             // include the advance of both the CPU and the PPU
-            counterCycles += this.gameBoy!.clock();
+            counterCycles += this.gameBoy?.clock() ?? 0;
 
             // in case the current PPU mode is VBlank and the
             // frame is different from the previously rendered
             // one then it's time to update the canvas
             if (
-                this.gameBoy!.ppu_mode() === PpuMode.VBlank &&
-                this.gameBoy!.ppu_frame() !== lastFrame
+                this.gameBoy?.ppu_mode() === PpuMode.VBlank &&
+                this.gameBoy?.ppu_frame() !== lastFrame
             ) {
-                lastFrame = this.gameBoy!.ppu_frame();
+                lastFrame = this.gameBoy?.ppu_frame();
 
                 // triggers the frame event indicating that
                 // a new frame is now available for drawing
@@ -354,7 +354,7 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
             const isArrow = ARROW_KEYS[event.key] ?? false;
             if (isArrow) event.preventDefault();
             if (keyCode !== undefined) {
-                this.gameBoy!.key_press(keyCode);
+                this.gameBoy?.key_press(keyCode);
                 return;
             }
 
@@ -374,7 +374,7 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
             const isArrow = ARROW_KEYS[event.key] ?? false;
             if (isArrow) event.preventDefault();
             if (keyCode !== undefined) {
-                this.gameBoy!.key_lift(keyCode);
+                this.gameBoy?.key_lift(keyCode);
                 return;
             }
         });
@@ -431,8 +431,8 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
 
     get romInfo(): RomInfo {
         return {
-            name: this.romName || undefined,
-            data: this.romData || undefined,
+            name: this.romName ?? undefined,
+            data: this.romData ?? undefined,
             size: this.romSize,
             extra: {
                 romType: this.cartridge?.rom_type_s(),
@@ -484,13 +484,13 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
     keyPress(key: string) {
         const keyCode = KEYS_NAME[key];
         if (keyCode === undefined) return;
-        this.gameBoy!.key_press(keyCode);
+        this.gameBoy?.key_press(keyCode);
     }
 
     keyLift(key: string) {
         const keyCode = KEYS_NAME[key];
         if (keyCode === undefined) return;
-        this.gameBoy!.key_lift(keyCode);
+        this.gameBoy?.key_lift(keyCode);
     }
 
     benchmark(count = 50000000) {
@@ -499,7 +499,7 @@ class GameboyEmulator extends EmulatorBase implements Emulator {
         try {
             const initial = Date.now();
             for (let i = 0; i < count; i++) {
-                cycles += this.gameBoy!.clock();
+                cycles += this.gameBoy?.clock() ?? 0;
             }
             const delta = (Date.now() - initial) / 1000;
             const frequency_mhz = cycles / delta / 1000 / 1000;
diff --git a/examples/web/react/components/button/button.tsx b/examples/web/react/components/button/button.tsx
index c65deb69..4c1ffda3 100644
--- a/examples/web/react/components/button/button.tsx
+++ b/examples/web/react/components/button/button.tsx
@@ -38,9 +38,8 @@ export const Button: FC<ButtonProps> = ({
             ...style
         ].join(" ");
     const onFileChange = (event: ChangeEvent<HTMLInputElement>) => {
-        if (!event.target.files || event.target.files.length === 0) {
-            return;
-        }
+        if (!event.target.files) return;
+        if (event.target.files.length === 0) return;
         const file = event.target.files[0];
         onFile && onFile(file);
         event.target.value = "";
@@ -66,7 +65,7 @@ export const Button: FC<ButtonProps> = ({
             onKeyPress={onKeyPress}
             tabIndex={focusable ? 0 : undefined}
         >
-            {image && <img src={image} alt={imageAlt || text || "button"} />}
+            {image && <img src={image} alt={imageAlt ?? text ?? "button"} />}
             {file && (
                 <input type="file" accept={accept} onChange={onFileChange} />
             )}
diff --git a/examples/web/react/components/keyboard-gb/keyboard-gb.tsx b/examples/web/react/components/keyboard-gb/keyboard-gb.tsx
index 1696c937..f6af2b52 100644
--- a/examples/web/react/components/keyboard-gb/keyboard-gb.tsx
+++ b/examples/web/react/components/keyboard-gb/keyboard-gb.tsx
@@ -27,50 +27,50 @@ export const KeyboardGB: FC<KeyboardGBProps> = ({
                 className={["key", pressed ? "pressed" : "", ...styles].join(
                     " "
                 )}
-                key={keyName || key}
+                key={keyName ?? key}
                 tabIndex={0}
                 onKeyDown={(event) => {
                     if (event.key !== "Enter") return;
                     setPressed(true);
-                    onKeyDown && onKeyDown(keyName || key);
+                    onKeyDown && onKeyDown(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onKeyUp={(event) => {
                     if (event.key !== "Enter") return;
                     setPressed(false);
-                    onKeyUp && onKeyUp(keyName || key);
+                    onKeyUp && onKeyUp(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onMouseDown={(event) => {
                     setPressed(true);
-                    onKeyDown && onKeyDown(keyName || key);
+                    onKeyDown && onKeyDown(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onMouseUp={(event) => {
                     setPressed(false);
-                    onKeyUp && onKeyUp(keyName || key);
+                    onKeyUp && onKeyUp(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onMouseLeave={(event) => {
                     if (!pressed) return;
                     setPressed(false);
-                    onKeyUp && onKeyUp(keyName || key);
+                    onKeyUp && onKeyUp(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onTouchStart={(event) => {
                     setPressed(true);
-                    onKeyDown && onKeyDown(keyName || key);
+                    onKeyDown && onKeyDown(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
                 onTouchEnd={(event) => {
                     setPressed(false);
-                    onKeyUp && onKeyUp(keyName || key);
+                    onKeyUp && onKeyUp(keyName ?? key);
                     event.stopPropagation();
                     event.preventDefault();
                 }}
diff --git a/examples/web/react/components/link/link.tsx b/examples/web/react/components/link/link.tsx
index 65046383..ee5b134b 100644
--- a/examples/web/react/components/link/link.tsx
+++ b/examples/web/react/components/link/link.tsx
@@ -20,7 +20,7 @@ export const Link: FC<LinkProps> = ({
     const classes = () => ["link", ...style].join(" ");
     return (
         <a className={classes()} href={href} target={target}>
-            {children || text}
+            {children ?? text}
         </a>
     );
 };
diff --git a/examples/web/react/components/overlay/overlay.tsx b/examples/web/react/components/overlay/overlay.tsx
index 1762dcf2..201d6d4b 100644
--- a/examples/web/react/components/overlay/overlay.tsx
+++ b/examples/web/react/components/overlay/overlay.tsx
@@ -16,31 +16,31 @@ export const Overlay: FC<OverlayProps> = ({ text, style = [], onFile }) => {
         ["overlay", visible ? "visible" : "", ...style].join(" ");
     useEffect(() => {
         const onDrop = async (event: DragEvent) => {
-            if (!event.dataTransfer!.items) return;
-            if (event.dataTransfer!.items[0].type) return;
+            if (!event.dataTransfer?.items) return;
+            if (event.dataTransfer?.items[0].type) return;
 
             setVisible(false);
 
-            const file = event.dataTransfer!.files[0];
+            const file = event.dataTransfer?.files[0];
             onFile && onFile(file);
 
             event.preventDefault();
             event.stopPropagation();
         };
         const onDragOver = async (event: DragEvent) => {
-            if (!event.dataTransfer!.items) return;
-            if (event.dataTransfer!.items[0].type) return;
+            if (!event.dataTransfer?.items) return;
+            if (event.dataTransfer?.items[0].type) return;
             setVisible(true);
             event.preventDefault();
         };
         const onDragEnter = async (event: DragEvent) => {
-            if (!event.dataTransfer!.items) return;
-            if (event.dataTransfer!.items[0].type) return;
+            if (!event.dataTransfer?.items) return;
+            if (event.dataTransfer?.items[0].type) return;
             setVisible(true);
         };
         const onDragLeave = async (event: DragEvent) => {
-            if (!event.dataTransfer!.items) return;
-            if (event.dataTransfer!.items[0].type) return;
+            if (!event.dataTransfer?.items) return;
+            if (event.dataTransfer?.items[0].type) return;
             setVisible(false);
         };
         document.addEventListener("drop", onDrop);
diff --git a/examples/web/react/components/panel-split/panel-split.tsx b/examples/web/react/components/panel-split/panel-split.tsx
index f394bbbd..10020f2f 100644
--- a/examples/web/react/components/panel-split/panel-split.tsx
+++ b/examples/web/react/components/panel-split/panel-split.tsx
@@ -19,7 +19,7 @@ export const PanelSplit: FC<PanelSplitProps> = ({
     return (
         <div className={classes()}>
             <div className="side-left">{left}</div>
-            <div className="side-right">{children || right}</div>
+            <div className="side-right">{children ?? right}</div>
         </div>
     );
 };
diff --git a/examples/web/react/components/paragraph/paragraph.tsx b/examples/web/react/components/paragraph/paragraph.tsx
index aeaa51dc..6d1efdb5 100644
--- a/examples/web/react/components/paragraph/paragraph.tsx
+++ b/examples/web/react/components/paragraph/paragraph.tsx
@@ -14,7 +14,7 @@ export const Paragraph: FC<ParagraphProps> = ({
     style = []
 }) => {
     const classes = () => ["paragraph", ...style].join(" ");
-    return <p className={classes()}>{children || text}</p>;
+    return <p className={classes()}>{children ?? text}</p>;
 };
 
 export default Paragraph;
-- 
GitLab