From 2ba17cb79e7248f7f243a16fac4eca2a91e376ae Mon Sep 17 00:00:00 2001
From: itsMapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com>
Date: Sat, 16 Jul 2022 12:07:17 -0500
Subject: [PATCH 1/4] fix: support undefined as optional keys in loader data

---
 .../remix-react/__tests__/hook-types-test.tsx | 10 ++++++++++
 packages/remix-react/components.tsx           | 19 ++++++++++++++-----
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/packages/remix-react/__tests__/hook-types-test.tsx b/packages/remix-react/__tests__/hook-types-test.tsx
index 8e7d998f8fa..acd2c96b0f4 100644
--- a/packages/remix-react/__tests__/hook-types-test.tsx
+++ b/packages/remix-react/__tests__/hook-types-test.tsx
@@ -100,4 +100,14 @@ describe("type serializer", () => {
     type response = UseDataFunctionReturn<Loader>;
     isEqual<response, { arg: string }>(true);
   });
+
+  it("makes keys optional if the value is undefined", () => {
+    type AppData = {
+      arg1: string;
+      arg2: number | undefined;
+      arg3: undefined;
+    };
+    type response = UseDataFunctionReturn<AppData>;
+    isEqual<response, { arg1: string; arg2?: number }>(true);
+  });
 });
diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx
index c702a514eb6..57bad60f397 100644
--- a/packages/remix-react/components.tsx
+++ b/packages/remix-react/components.tsx
@@ -1336,6 +1336,7 @@ type JsonPrimitives =
   | Boolean
   | null;
 type NonJsonPrimitives = undefined | Function | symbol;
+
 type SerializeType<T> = T extends JsonPrimitives
   ? T
   : T extends NonJsonPrimitives
@@ -1353,13 +1354,21 @@ type SerializeType<T> = T extends JsonPrimitives
   : T extends (infer U)[]
   ? (U extends NonJsonPrimitives ? null : SerializeType<U>)[]
   : T extends object
-  ? {
-      [k in keyof T as T[k] extends NonJsonPrimitives
-        ? never
-        : k]: SerializeType<T[k]>;
-    }
+  ? SerializeObject<UndefinedOptionals<T>>
   : never;
 
+type SerializeObject<T> = {
+  [k in keyof T as T[k] extends NonJsonPrimitives ? never : k]: SerializeType<
+    T[k]
+  >;
+};
+
+type UndefinedOptionals<T> = {
+  [k in keyof T as undefined extends T[k] ? never : k]: NonNullable<T[k]>;
+} & {
+  [k in keyof T as undefined extends T[k] ? k : never]?: NonNullable<T[k]>;
+};
+
 export type UseDataFunctionReturn<T extends DataOrFunction> = T extends (
   ...args: any[]
 ) => infer Output

From 70d3c9b609871ef9f8cf4421bf792f8a5df7acaa Mon Sep 17 00:00:00 2001
From: itsMapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com>
Date: Sat, 16 Jul 2022 12:13:11 -0500
Subject: [PATCH 2/4] add to contributors

---
 contributors.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/contributors.yml b/contributors.yml
index e4f12650499..d1929c13f71 100644
--- a/contributors.yml
+++ b/contributors.yml
@@ -153,6 +153,7 @@
 - isaacrmoreno
 - ishan-me
 - IshanKBG
+- itsMapleLeaf
 - jacob-ebey
 - JacobParis
 - jakewtaylor

From 37e7fc5593130986f9cd90c448af0d66075db87e Mon Sep 17 00:00:00 2001
From: itsMapleLeaf <19603573+itsMapleLeaf@users.noreply.github.com>
Date: Wed, 27 Jul 2022 09:02:12 -0500
Subject: [PATCH 3/4] use Merge for cleaner type

---
 packages/remix-react/components.tsx | 14 +++++++++-----
 packages/remix-react/package.json   |  3 ++-
 yarn.lock                           |  5 +++++
 3 files changed, 16 insertions(+), 6 deletions(-)

diff --git a/packages/remix-react/components.tsx b/packages/remix-react/components.tsx
index 57bad60f397..faf4592d241 100644
--- a/packages/remix-react/components.tsx
+++ b/packages/remix-react/components.tsx
@@ -20,6 +20,7 @@ import {
   useResolvedPath,
 } from "react-router-dom";
 import type { LinkProps, NavLinkProps } from "react-router-dom";
+import type { Merge } from "type-fest";
 
 import type { AppData, FormEncType, FormMethod } from "./data";
 import type { EntryContext, AssetsManifest } from "./entry";
@@ -1363,11 +1364,14 @@ type SerializeObject<T> = {
   >;
 };
 
-type UndefinedOptionals<T> = {
-  [k in keyof T as undefined extends T[k] ? never : k]: NonNullable<T[k]>;
-} & {
-  [k in keyof T as undefined extends T[k] ? k : never]?: NonNullable<T[k]>;
-};
+type UndefinedOptionals<T> = Merge<
+  {
+    [k in keyof T as undefined extends T[k] ? never : k]: NonNullable<T[k]>;
+  },
+  {
+    [k in keyof T as undefined extends T[k] ? k : never]?: NonNullable<T[k]>;
+  }
+>;
 
 export type UseDataFunctionReturn<T extends DataOrFunction> = T extends (
   ...args: any[]
diff --git a/packages/remix-react/package.json b/packages/remix-react/package.json
index 3c136aa7354..6a7609f1220 100644
--- a/packages/remix-react/package.json
+++ b/packages/remix-react/package.json
@@ -17,7 +17,8 @@
   "module": "dist/esm/index.js",
   "dependencies": {
     "history": "^5.3.0",
-    "react-router-dom": "^6.2.2"
+    "react-router-dom": "^6.2.2",
+    "type-fest": "^2.17.0"
   },
   "devDependencies": {
     "@testing-library/jest-dom": "^5.16.2",
diff --git a/yarn.lock b/yarn.lock
index e775d57ae5a..ba30b90380a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -12127,6 +12127,11 @@ type-fest@^2.16.0:
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.16.0.tgz#1250fbd64dafaf4c8e405e393ef3fb16d9651db2"
   integrity sha512-qpaThT2HQkFb83gMOrdKVsfCN7LKxP26Yq+smPzY1FqoHRjqmjqHXA7n5Gkxi8efirtbeEUxzfEdePthQWCuHw==
 
+type-fest@^2.17.0:
+  version "2.17.0"
+  resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.17.0.tgz#c677030ce61e5be0c90c077d52571eb73c506ea9"
+  integrity sha512-U+g3/JVXnOki1kLSc+xZGPRll3Ah9u2VIG6Sn9iH9YX6UkPERmt6O/0fIyTgsd2/whV0+gAaHAg8fz6sG1QzMA==
+
 type-is@^1.6.18, type-is@~1.6.18:
   version "1.6.18"
   resolved "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz"

From 26fe8c8792dd22f1967c4ba7f7e2f46af0af6045 Mon Sep 17 00:00:00 2001
From: Pedro Cattori <pcattori@gmail.com>
Date: Wed, 27 Jul 2022 11:18:41 -0400
Subject: [PATCH 4/4] Create olive-pumpkins-kick.md

---
 .changeset/olive-pumpkins-kick.md | 6 ++++++
 1 file changed, 6 insertions(+)
 create mode 100644 .changeset/olive-pumpkins-kick.md

diff --git a/.changeset/olive-pumpkins-kick.md b/.changeset/olive-pumpkins-kick.md
new file mode 100644
index 00000000000..0c42a921230
--- /dev/null
+++ b/.changeset/olive-pumpkins-kick.md
@@ -0,0 +1,6 @@
+---
+"remix": patch
+"@remix-run/react": patch
+---
+
+support undefined unions as optional keys in `UseDataFunctionReturn` type