Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

fix: avoid circular references and infinitely recursive types #6736

Merged
merged 1 commit into from
Jun 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions .changeset/popular-beers-bake.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
"@remix-run/server-runtime": patch
---

Avoid circular references and infinite recursion in types

"Pretty" or simplified Typescript types are evaluated by eagerly resolving types.
For complex types with circular references, this can cause TS to recurse infinitely.

To fix this, pretty types are reverted as a built-in DX feature of useLoaderData, useActionData, etc...
8 changes: 2 additions & 6 deletions packages/remix-server-runtime/serialize.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import type { AppData } from "./data";
import type { TypedDeferredData, TypedResponse } from "./responses";

// force Typescript to simplify the type
type Pretty<T> = { [K in keyof T]: T[K] } & {};
type PrettyTransform<T, U> = [T] extends [U] ? T : Pretty<U>;

type JsonPrimitive =
| string
| number
Expand All @@ -29,9 +25,9 @@ type Serialize<T> =
T extends NonJsonPrimitive ? never :
T extends { toJSON(): infer U } ? U :
T extends [] ? [] :
T extends [unknown, ...unknown[]] ? PrettyTransform<T, SerializeTuple<T>> :
T extends [unknown, ...unknown[]] ? SerializeTuple<T> :
T extends ReadonlyArray<infer U> ? (U extends NonJsonPrimitive ? null : Serialize<U>)[] :
T extends object ? PrettyTransform<T, SerializeObject<UndefinedToOptional<T>>> :
T extends object ? SerializeObject<UndefinedToOptional<T>> :
never
;

Expand Down